Node和Web的事件循环(EventLoop)机制的异同

82 阅读1分钟

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 浏览器处理流程是:

  1. 整段代码为一个宏任务,运行后产生两个setTimeout宏任务,加入到宏任务队列,无微任务队列;
  2. 然后到时间后会从宏任务队列中取出宏任务队列中的第一个setTimeOut,从而输出timer1,随后产生一个微任务,加入到微任务队列,宏任务执行完后,就去清空微任务队列,输出promise1
  3. 同2,执行后输出timer2->promise2 Noded端输出结果是timer1->timer2->promise1->promise2 Node执行过程为
  4. 全局脚本(main())执行,将2个timer依次放入timer队列,main()执行完毕,调用栈空闲,任务队列开始执行;
  5. 首先进入timers阶段,执行time1的回调函数,打印time1,并将promise1.then回调放入微任务队列,同样的步骤执行time2,打印time2
  6. 至此,timer阶段执行结束,event loop进入下一个阶段之前,执行微任务队列中的所有任务,依次打印promise1->promise2