阅读 141

Event Loop 记录

事件循环

  1. 同步任务和异步任务分别进入不同的线程,同步任务进入主线程,异步任务进入 Event Table 并注册函数(如果是 setTimeout 则开始计时)
  2. 指定任务完成时(获取到结果、计时完成)Event Table 会把对应的回调函数移入 Event Queue
  3. 主线程内的任务执行完毕后,会去 Event Queue 读取对应的函数,进入主线程执行

这个过程会不断重复,这就是事件循环

js 引擎存在 monitoring process 进程,会持续不断检查主线程执行栈是否为空,一旦为空就去 Event Queue 检查是否有待执行函数

image.png

宏任务和微任务

宏任务: 包括整体代码 script ,setTimeout,setInterval,setImmediate 微任务: 原生 Promise,promise.then(有些实现把 then 放到了宏任务中,这个我也不太明白),process.nextTick,MutationOberve

image.png

console.log('start');  // 输出

setTimeout(() => {   // 放入宏任务 EventQueue
    console.log('timeout1');
    let p = new Promise(function(resolve, reject) {
        console.log('promise3');
        resolve('ok');
    });
    p.then((val) => {
        console.log(val);
    });
}, 0);

new Promise(function(resolve, reject) {
    console.log('promise1'); // 执行
    setTimeout(() => { // 放入宏任务 Event Queue
        console.log('timeout2');
    }, 0);
    
    new Promise((resolve, reject) => {
        console.log('promise2');
        resolve();
    }).then(()=>{
        console.log('then1');
    });
    resolve();
}).then(()=>{
    console.log('then2');
});

console.log('end?');
复制代码

执行顺序:

  1. 输出 start,将 setTimeout 放入宏任务的 Event Queue,输出 promise1,将 setTimeout 放入宏任务的 Event Queue,输出 promise2,把 then1 放入微任务的 Event Queue,把 then2 放入微任务的 Event Queue,输出 end?

主线程执行完毕,此时宏任务的 Event Queue 里面有 两个 setTimeout,微任务的 Event Queue 里有 then1then2,按照队列先进先出,所以先放入的先执行,输出 then1, then2,微任务执行完毕,开始新的宏任务,即第一个setTimeout

  1. 输出 timeout1,输出 promise3,将 ok 放入微任务队列,执行微任务队列的任务,输出 ok,此时宏任务 Event Queeu 中还有一个,微任务队列空了,开始下一个宏任务

  2. 输出 timeout2,至此所有任务执行完毕

**输出顺序为 start, promise1, promise2, end?, then1, then2, timeout1, promise3, ok, timeout2 **

image.png

最后,中间的有一个 undefined 看起来应该不是代码输出的,可能是某个函数的返回,暂时没有搞明白,对 Promise 理解还不够深入,记录一下

参考 juejin.cn/post/684490…

文章分类
前端
文章标签