Node.js 之 setTimeout & setImmediate & process.nextTick
Node.js 之 setTimeout & setImmediate & process.nextTick
setImmediate vs. nextTick
setImmediate 在已在事件队列的 I/O 事件触发之后发生,process.nextTick在事件队列之前,并且在当前函数结束之后发生。
因此,如果你打算打断长运行、使用递归的 cpu 任务,你可以使用setImmediate 而非process.nextTick来插入下一个迭代,否则任何 I/O 事件回调没有任何机会在迭代过程中被调用。
另外:
传递到process.nextTick的回调函数通常在执行事件流的最后被调用,因此最适合用于尽可能快的同步操作。如果未做检查,这将会消耗掉event loop,阻止 I/O 发生。setImmediates则按创建顺序插入队列,并且在每一次迭代过程中弹出。这与process.nextTick有很大不同,process.nextTick会在每一次迭代的时候执行process.maxTickDepth队列回调函数。setImmediate在触发队列回调函数之后会让步于event loop,以确保 I/O 不会被消耗掉。
我的理解是:process.nextTick会阻塞 I/O。
setTimeout vs. setImmediate
setTimeout只是简单饿在一定时间的延迟后来调用函数,无论何时延迟方法被调用,该方法都不是立即执行的,而是等队列中当前所有的事务方法全部执行完成后才调用。所以setTimeout(fn,0)不是立即执行,而是等到当前队列中所有的方法全部执行完毕后再执行。无法保证运行时间的准确性。
setImmediate在上述的点上和setTimeout很类似,但区别是它不使用方法队列。它会检测 I/O 事件处理队列。如果所有的 I/O 事件在当前时间点已经处理完毕,则它会去执行回调函数。在最后一个 I/O 处理完毕后,它立即将他们(回调函数)排入队列。这一点有点像process.nextTick,所以它更快。
另外,setTimeout(fn,0)会比较慢还有一个原因是它至少会在执行前检测一次定时器。