Node与浏览器的Event Loop差异
浏览器环境下,microtask的任务队列是每个宏任务队列执行完之后执行。而在Node.js中,微任务队列会在事件循环的各个阶段之间执行,也就是一个阶段执行完毕,就会去执行微任务队列。 比如下面这个例子
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 浏览器处理流程是:
- 整段代码为一个宏任务,运行后产生两个setTimeout宏任务,加入到宏任务队列,无微任务队列;
- 然后到时间后会从宏任务队列中取出宏任务队列中的第一个setTimeOut,从而输出
timer1,随后产生一个微任务,加入到微任务队列,宏任务执行完后,就去清空微任务队列,输出promise1; - 同2,执行后输出timer2->promise2 Noded端输出结果是timer1->timer2->promise1->promise2 Node执行过程为
- 全局脚本(main())执行,将2个timer依次放入timer队列,main()执行完毕,调用栈空闲,任务队列开始执行;
- 首先进入timers阶段,执行time1的回调函数,打印time1,并将promise1.then回调放入微任务队列,同样的步骤执行time2,打印time2
- 至此,timer阶段执行结束,event loop进入下一个阶段之前,执行微任务队列中的所有任务,依次打印promise1->promise2