回答
具体分析
执行顺序图例
在一个 EventLoop 中,先执行宏任务,再执行微任务,全部执行后开始新的 EventLoop。
其中:
- 主线程:执行同步任务。
- 宏任务(macro-task)队列:setTimeout,setInterval
- 微任务(micro-task)队列:Promise
一个小例子
```typescript // 以下代码的执行顺序
setTimeout(() => {
console.log(1); // 1
});
new Promise(res => {
console.log(2); // 2
res();
}).then(() => {
Promise.resolve().then(() => {
console.log(3); // 3
});
console.log(4); // 4
setTimeout(() => {
console.log(5); // 5
});
});
console.log(6); // 6
```
正确答案是:2 6 4 3 1 5。
为什么?(为了简化描述,1 表示 1 所在的函数)
- 1 推入下一轮 EventLoop 的宏任务队列,因为在 setTimeout 中,且其时间参数为 0。
- 2 推入主线程,因为 Promise 具有创建即执行的机制。
- 345 推入微任务队列,因为在 Promise.then 中。
- 6 推入主线程。
- 执行主线程,输出:2 6。
- 执行当前宏任务队列,没有。
- 执行当前微任务队列,执行345函数。
- 3 会推入微队列。
- 4 会推入主线程执行,输出:4。
- 5 会推入下一轮 EventLoop 的宏任务队列,但下一轮有宏任务,所以会推入下下一轮。
- 微任务中还有新加的 3,推入主线程执行,输出:3。
- 本轮 EventLoop 结束,进入下一轮 EventLoop,输出:1。
-
参考资料
10分钟理解JS引擎的执行机制_前端进阶 - SegmentFault 思否 [https://segmentfault.com/a/1190000012806637]