浏览器环境下,microtask 的任务队列是每个 macrotask 执行完之后执行。而在 Node.js 中,microtask 会在事件循环的各个阶段之间执行,也就是一个阶段执行完毕,就会去执行 microtask 队列的任务。
接下我们通过一个例子来说明两者区别:
setTimeout(()=>{
console.log('timer1')
Promise.resolve().then(function() {
console.log('promise1')
})
}, 0)
setTimeout(()=>{
console.log('timer2')
Promise.resolve().then(function() {
console.log('promise2')
})
}, 0)
浏览器端运行结果:timer1=>promise1=>timer2=>promise2
Node 端运行结果分两种情况:
-
如果是 node11 版本一旦执行一个阶段里的一个宏任务(setTimeout,setInterval 和 setImmediate)就立刻执行微任务队列,这就跟浏览器端运行一致,最后的结果为
timer1=>promise1=>timer2=>promise2 -
如果是 node10 及其之前版本:要看第一个定时器执行完,第二个定时器是否在完成队列中。
- 如果是第二个定时器还未在完成队列中,最后的结果为
timer1=>promise1=>timer2=>promise2 - 如果是第二个定时器已经在完成队列中,则最后的结果为
timer1=>timer2=>promise1=>promise2(下文过程解释基于这种情况下)
1.全局脚本(main())执行,将 2 个 timer 依次放入 timer 队列,main()执行完毕,调用栈空闲,任务队列开始执行;
2.首先进入 timers 阶段,执行 timer1 的回调函数,打印 timer1,并将 promise1.then 回调放入 microtask 队列,同样的步骤执行 timer2,打印 timer2;
3.至此,timer 阶段执行结束,event loop 进入下一个阶段之前,执行 microtask 队列的所有任务,依次打印 promise1、promise2
- 如果是第二个定时器还未在完成队列中,最后的结果为
文章比较了浏览器环境下microtask与Node.js中不同版本microtask的执行顺序,通过setTimeout和Promise示例展示了在Node11和Node10及以下版本中,微任务处理的差异。
815

被折叠的 条评论
为什么被折叠?



