【Node.js】Event Loop执行顺序详解

本文基于node 0.10.22版本

 

关于EventLoop是什么,请看阮老师写的什么是EventLoop

 

本文讲述的是EventLoop中的执行顺序(着重讲setImmediate, setTimeout/setInterval, I/O的顺序)

 

首先看看github上看到的nodejs eventloop 的图解, 来源于https://github.com/joyent/node/issues/6034#issuecomment-30017889

nodejs event loop 图解 

(注意图中timers处process.nextTick仍可以优先于timers处执行,可能是图中有遗漏, 任何回调中设置的nextTick都会在回调结束时最优先调用,所有nextTick执行完毕才会继续EventLoop的遍历)

解释一下:

每一次EventLoop会按以下顺序遍历 timers ->poll(I/O)->check(immediates)

  • timers阶段会将达到延时的回调依次执行完,该阶段中设置的timers都不会在该次event loop中执行,即使已到达延时
  • poll阶段会将已返回数据的I/O回调依次执行完毕,该阶段设置的I/O都不会在该次event loop中执行,即使数据已经返回
  • check阶段将只执行一个最先设置的immediate回调,就跳出该阶段了
  • timers阶段若设置了I/O任务,并且在poll阶段前数据就已经返回,该I/O回调将会在该次event loop的poll阶段执行
  • timers和poll阶段若设置了immediates的回调,并且此回调是最先设置的回调,则该回调会在该次event loop的check阶段执行
setTimeout(function(){
//第一次进入event loop
  console.log('setTimeout - 1');
  //timers中设置的timers只会在下次event loop中执行
  setTimeout(function(){
    console.log('setTimeout - 2');
  }, 0)
  //timers中设置的io延时足够低时将在这次event loop中执行
  fs.stat('file', function(){
    console.log('I/O');
  }) ;
  //timers或poll阶段设置的immediate回调若是该immediates回调数组中的第一个,将在这次Event loop中执行
  setImmediate(function(){
    console.log('setImmediate');
  }) ;
}, 0);

 

注意: 一个eventloop的时间并不确定,我们不能确定程序处于哪个阶段处于哪个eventloop,能确定的只有[同一个eventloop内的执行顺序]

 

 

送上负责nodejs的event loop部分(c++)的libuv库的介绍:http://nikhilm.github.io/uvbook/index.html

 

补充一下:(个人理解)

 

idle阶段指的是进程属于闲置状态,没有更多的事件需要处理

prepare阶段指的是进程开始阻塞(也就是同步代码开始运行)前的阶段

(刚接触nodejs,还没了解到有哪些借口可以为这两个阶段设置回调)

check阶段指的是进程阻塞完毕后的阶段

posted @ 2013-12-05 18:27  will_kan  阅读(2527)  评论(0编辑  收藏  举报