JS 执行机制 详解(附图)

一、JS是单线程

JS语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是JS这门脚本语言诞生的使命所致——用来处理页面中用户的交互,以及操作DOM而诞生的。

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是:如果JS执行的时间过长,这样会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉

二、同步和异步

为了解决这个问题,利用多核CPU的计算能力,HTML5提出了Web Worker标准,允许JS脚本创建多个线程,于是,jS中出现了同步和异步

同步:前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的,同步的。比如:我们要烧水煮饭,等水开了(10分钟后),再去切菜,炒菜

异步:你在做一件事情时,因为这件事会花费很长时间,在做这件事的同时,你还可以去处理其他事情。比如烧水的10分钟内,去切菜,炒菜

同步任务在主线程上排队执行任务,只有前一个任务执行完毕,才能执行后一个任务

异步任务:不进入主线程,而是进入"任务队列"的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

一般而言,异步任务有以下四种类型

  • setTimeout和setlnterval

  • DOM事件 普通事件如:click、resize,资源加载事件:onload等

  • ES6中的Promise

  • Ajax异步请求

异步任务相关回调函数添加到任务队列中(消息队列)

三、JS执行机制

  1. 先执行执行栈中的同步任务

  1. 异步任务(回调函数)放入任务队列中

  1. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行

let setTimeoutCallBack = function() {
  console.log('我是定时器回调');
};
let httpCallback = function() {
  console.log('我是http请求回调');
}

// 同步任务
console.log('我是同步任务1');

// 异步定时任务
setTimeout(setTimeoutCallBack,1000);

// 异步http请求任务
ajax.get('/info',httpCallback);

// 同步任务
console.log('我是同步任务2');

上述代码执行过程:

JS是按照顺序从上往下依次执行的,可以先理解为这段代码时的执行环境就是主线程,也就是当前执行栈

首先,执行console.log(‘我是同步任务1’)

接着,执行到setTimeout时,会移交给定时器线程,通知定时器线程 1s 后将setTimeoutCallBack 这个回调交给事件触发线程处理,在 1s 后事件触发线程会收到 setTimeoutCallBack 这个回调并把它加入到事件触发线程所管理的事件队列中等待执行

接着,执行http请求,会移交给异步http请求线程发送网络请求,请求成功后将 httpCallback 这个回调交由事件触发线程处理,事件触发线程收到 httpCallback 这个回调后把它加入到事件触发线程所管理的事件队列中等待执行

再接着执行console.log(‘我是同步任务2’)

至此主线程执行栈中执行完毕,JS引擎线程已经空闲,开始向事件触发线程发起询问,询问事件触发线程的事件队列中是否有需要执行的回调函数,如果有将事件队列中的回调事件加入执行栈中,开始执行回调,如果事件队列中没有回调,JS引擎线程会一直发起询问,直到有为止

由此可以看出,浏览器上的所有线程的工作都很单一且独立,非常符合单一原则

定时触发线程 只管理定时器且只关注定时不关心结果,定时结束就把回调扔给事件触发线程

异步http请求线程 只管理http请求同样不关心结果,请求结束把回调扔给事件触发线程

事件触发线程 只关心异步回调入事件队列

JS引擎线程 只会执行执行栈中的事件,执行栈中的代码执行完毕,就会读取事件队列中的事件并添加到执行栈中继续执行,这样反反复复就是我们所谓的事件循环(Event Loop)

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
WebSocket是一种基于TCP协议的全双工通信协议,可以在客户端和服务器之间建立实时的双向通信。Java和JS都提供了对WebSocket的支持,下面分别介绍它们的代码机制。 Java的WebSocket代码机制: 1. 引入WebSocket依赖 在Maven项目中,可以在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>org.glassfish.tyrus</groupId> <artifactId>tyrus-server</artifactId> <version>1.13.1</version> </dependency> ``` 2. 创建服务器端点 使用javax.websocket.server.ServerEndpoint注解创建WebSocket服务器端点,指定路径和处理类: ``` @ServerEndpoint("/websocket") public class WebSocketServer { // 处理连接建立事件 @OnOpen public void onOpen(Session session) { // ... } // 处理收到消息事件 @OnMessage public void onMessage(String message, Session session) { // ... } // 处理连接关闭事件 @OnClose public void onClose(Session session) { // ... } // 处理错误事件 @OnError public void onError(Throwable error) { // ... } } ``` 3. 启动WebSocket服务器 使用javax.websocket.server.ServerContainer启动WebSocket服务器,指定端口和路径: ``` Server server = new Server("localhost", 8080, "/path"); ServerContainer container = ContainerProvider.getWebSocketContainer(); container.addEndpoint(server); server.start(); ``` 4. 创建WebSocket客户端 使用javax.websocket.ClientEndpoint注解创建WebSocket客户端,指定路径和处理类: ``` @ClientEndpoint("/websocket") public class WebSocketClient { // 处理连接建立事件 @OnOpen public void onOpen(Session session) { // ... } // 处理收到消息事件 @OnMessage public void onMessage(String message, Session session) { // ... } // 处理连接关闭事件 @OnClose public void onClose(Session session) { // ... } // 处理错误事件 @OnError public void onError(Throwable error) { // ... } } ``` 5. 连接WebSocket服务器 使用javax.websocket.ClientManager连接WebSocket服务器,指定路径和URI: ``` ClientEndpointConfig config = ClientEndpointConfig.Builder.create().build(); ClientManager client = ClientManager.createClient(); client.connectToServer(new WebSocketClient(), config, new URI("ws://localhost:8080/path")); ``` JS的WebSocket代码机制: 1. 创建WebSocket对象 使用WebSocket构造函数创建WebSocket对象,指定服务器地址和路径: ``` var socket = new WebSocket("ws://localhost:8080/path"); ``` 2. 注册事件处理程序 使用WebSocket对象的onopen、onmessage、onclose和onerror属性注册事件处理程序: ``` socket.onopen = function(event) { // ... }; socket.onmessage = function(event) { // ... }; socket.onclose = function(event) { // ... }; socket.onerror = function(event) { // ... }; ``` 3. 发送消息 使用WebSocket对象的send方法发送消息: ``` socket.send("Hello, server!"); ``` 以上便是Java和JS的WebSocket代码机制详解

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

燕穗子博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值