浏览器事件循环机制(Event Loop)(下)

这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

接上一篇:juejin.cn/post/703286… 浏览器事件循环机制(Event Loop)(上)继续展开相关内容的描述。

前言

在事件循环机制(Event Loop)(上)中,主要介绍了相关概念,本篇将具体介绍事件循环机制的运行步骤及相关demo。

事件循环机制

  • 执行一个宏任务(栈中没有就从事件队列中获取);
  • 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中;
  • 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行);
  • 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染;
  • 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)。

下图非常详细地描述了事件处理过程: image.png

其实说白了就是首先会去执行一个宏任务,如果宏任务队列中没有宏任务呢?那就从事件队列中获取。不过在该宏任务执行过程中,如果遇到微任务了,不管遇到几个,都会将微任务放入到微任务队列当中,直到该宏任务执行完毕,会从队列中弹出;紧接着会去执行刚才加入到微任务队列当中的微任务;好啦,刚才那些微任务都执行完毕了,那就再去宏任务队列中看看还有没有宏任务,有的话继续执行任务队列中的第一个宏任务,没有的话就去看看微任务队列中有没有微任务。最后的最后,宏任务和微任务都执行完毕了,那就开始渲染了。

Event Loop demo

demo 1:

console.log("我是开始");         //主程序代码(宏任务1)
 
setTimeout(function() {         //产生了一个新的宏任务2——————放入宏任务队列
  console.log('setTimeout');
}, 0);
 
Promise.resolve().then(function() {    //产生了微任务1——————放入微任务队列
  console.log('promise1');
}).then(function() {                   //产生了微任务2——————放入微任务队列
  console.log('promise2');
});
 
console.log('我是结束');        //主程序代码(宏任务1)
复制代码

上述代码打印顺序:我是开始 VM146:13 我是结束 VM146:8 promise1 VM146:10 promise2 VM146:4 setTimeout

上述代码会先执行宏任务1,执行过程中遇到setTimeout这个宏任务,会将他放入到宏任务队列;又遇到了微任务1,2,将他们依次放入微任务队列中。执行完宏任务1后,会立即执行刚才执行过程中插入微任务队列的微任务,全部执行完刚才入队的微任务,然后去执行宏任务队列中的宏任务。 demo 2:

async function async1() {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}
async function async2() {
    console.log('async2');
}
 
console.log('script start');
 
setTimeout(function() {
    console.log('setTimeout');
}, 0)
 
async1();
 
new Promise(function(resolve) {
    console.log('promise1');
    resolve();
}).then(function() {
    console.log('promise2');
});
console.log('script end');
*/
复制代码

image.png

注:

1.async函数中在await之前的代码是立即执行的,所以会立即输出async1 start。 遇到了await时,会将await后面的表达式执行一遍,所以就紧接着输出async2,然后将await后面的代码也就是console.log('async1 end')加入到微任务队列中的Promise队列中,接着跳出async1函数来执行后面的代码。

扫描二维码关注公众号,回复: 13317300 查看本文章

2.Promise中的函数是立即执行的,而后续的 .then 则会被分发到微任务队列的 Promise 队列中去。所以会先输出 promise1,然后执行 resolve,将 promise2 分配到对应队列。

总结

到目前为止,浏览器的事件循环机制就介绍完啦,希望我们都可以有所收获。

Happy Ending.

猜你喜欢

转载自juejin.im/post/7033955054629584909