936 字
5 分钟
Event Loop轮询处理线程

首先要明白,

  1. js代码里头 有同步的任务,是由JS引擎线程处理,也就是主线程,同步任务都在主线程(这里的主线程就是JS引擎线程)上执行 ,形成一个执行栈
  2. js代码里头 有异步的任务,各种各样的异步任务,各种各样的异步任务在各个对应的线程中进行处理,比如settimeout异步任务就在定时触发器线程中处理,ajax,fetch这些的js库的本质的请求代码是由异步http请求线程处理的。
  3. 主线程,之外还有一个 任务队列,这个任务队列归 事件触发线程 管, 只要异步任务有了运行结果 ,就在这个任务队列中加一个它的事件回调。

一旦执行栈中的所有同步任务执行完毕(也就是JS引擎线程空闲了),系统就会读取任务队列,将可运行的异步任务(任务队列中的事件回调,只要任务队列中有事件回调,就说明可以执行)添加到执行栈中,开始执行

这个过程可以简单概括为,上面这3个东西之间的交流,他们交流的中介,就是 EventLoop轮询处理线程 , 既然叫轮询了,那么肯定是不断的循环的去交流和沟通

看一段代码

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

以下是顺序

  1. 执行console.log('我是同步任务1') ,主线程中运行
  2. 接着,执行到setTimeout时会
  • 移交给定时触发器线程 ,通知定时触发器线程 1s 后将 setTimeoutCallBack 这个回调交给事件触发线程处理
  • 在 1s 后事件触发线程会收到 setTimeoutCallBack 这个回调并把它加入到事件触发线程所管理的事件队列中等待执行
  1. 执行http请求
  • 移交给异步http请求线程发送网络请求
  • 请求成功后将 httpCallback 这个回调交由事件触发线程处理,事件触发线程收到 httpCallback 这个回调后把它加入到事件触发线程所管理的事件队列中等待执行
  1. 执行console.log('我是同步任务2')
  2. 主线程执行栈中执行完毕 ,JS引擎已经空闲了, 向事件触发线程发起询问,询问事件触发线程的事件队列中是否有需要执行的回调函数
  • 如果有将事件队列中的回调事件加入执行栈中,开始执行回调
  • 如果事件队列中没有回调,JS引擎线程会一直发起询问,直到有为止

图解Event Loop

图解Event Loop

首先,执行栈开始顺序执行

判断是否为同步,异步则进入异步线程,最终事件回调给事件触发线程的任务队列等待执行,同步继续执行

执行栈空,询问任务队列中是否有事件回调

任务队列中有事件回调则把回调加入执行栈末尾继续从第一步开始执行

任务队列中没有事件回调则不停发起询问

完整的图解Event loop可以再结合宏任务和微任务得出

Event Loop轮询处理线程
https://nollieleo.github.io/posts/event-loop轮询处理线程/
作者
翁先森
发布于
2021-06-10
许可协议
CC BY-NC-SA 4.0