码迷,mamicode.com
首页 > 其他好文 > 详细

Event Loop

时间:2020-03-14 16:45:26      阅读:61      评论:0      收藏:0      [点我收藏+]

标签:规范   开始   end   set   图片   interval   ESS   分配   str   

当我们执行 JS 代码的时候其实就是往执行栈中放入函数,那么遇到异步代码的时候该怎么办?其实当遇到异步的代码时,会被挂起并在需要执行的时候加入到 Task(有多种 Task) 队列中。一旦执行栈为空,Event Loop 就会从 Task 队列中拿出需要执行的代码并放入执行栈中执行,所以本质上来说 JS 中的异步还是同步行为。

技术图片

 

 

不同的任务源会被分配到不同的 Task 队列中,任务源可以分为 微任务(microtask) 和 宏任务(macrotask)。在 ES6 规范中,microtask 称为 jobs,macrotask 称为 task

所以 Event Loop 执行顺序如下所示:

  • 首先执行同步代码,这属于宏任务
  • 当执行完所有同步代码后,执行栈为空,查询是否有异步代码需要执行
  • 执行所有微任务
  • 当执行完所有微任务后,如有必要会渲染页面
  • 然后开始下一轮 Event Loop,执行宏任务中的异步代码,也就是 setTimeout 中的回调函数

微任务包括 process.nextTickpromiseMutationObserver,其中 process.nextTick 为 Node 独有。

宏任务包括 scriptsetTimeoutsetIntervalsetImmediateI/OUI rendering

这里很多人会有个误区,认为微任务快于宏任务,其实是错误的。因为宏任务中包括了 script ,浏览器会先执行一个宏任务,接下来有异步代码的话才会先执行微任务。

console.log(‘script start‘);

setTimeout(function() {
  console.log(‘timeout1‘);
}, 10);

new Promise(resolve => {
    console.log(‘promise1‘);
    resolve();
    setTimeout(() => console.log(‘timeout2‘), 10);
}).then(function() {
    console.log(‘then1‘)
})

console.log(‘script end‘);

 

简要解释一下:

  最初始,宏任务队列中,只有一个script任务,首先遇到了console.log,输出 script start; 接着往下走,遇到setTimeOut,将其分发到宏队列;接着遇到 promise,new promise 中的代码立即执行,输出 promise1, 然后执行 resolve ,遇到 setTimeout ,将其分发到宏队列中去,记为 timemout2, 将其 then 分发到微任务队列中去,记为 then1;接着遇到 console.log 代码,直接输出 script end。

  接着检查微任务队列,发现有个 then1 微任务,执行,输出then1 再检查微任务队列,发现已经清空。开始检查宏任务队列,执行 timeout1,输出 timeout1; 接着执行 timeout2,输出 timeout2 至此,所有的都队列都已清空,执行完毕。

 

Event Loop

标签:规范   开始   end   set   图片   interval   ESS   分配   str   

原文地址:https://www.cnblogs.com/lora404/p/12492441.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!