在setTimeout()函数之后调用setImmediate()函数

在nodejs的官方网站( https://nodejs.org/api/timers.html#timers_setimmediate_callback_arg ),据说:

setImmediate()函数调度I / O事件的callback之后,setTimeout和setInterval设置的定时器被触发之后,立即执行callback。

但是在下面的代码中,setTimeout()函数在setImmediate()之前执行。 为什么?

setImmediate(function A() { setImmediate(function B() { console.log(1); setImmediate(function D() { console.log(2); }); setImmediate(function E() { console.log(3); }); }); setImmediate(function C() { console.log(4); setImmediate(function F() { console.log(5); }); setImmediate(function G() { console.log(6); }); }); }); setTimeout(function timeout() { console.log('TIMEOUT FIRED'); }, 0) 

结果:

 TIMEOUT FIRED
 1
 4
 2
 3
五
 6

我写了另外一个例子, setTimeout setImmediate之前工作。

 setTimeout(function timeout() { console.log('TIMEOUT-1 FIRED'); }, 0) setTimeout(function timeout() { console.log('TIMEOUT-2 FIRED'); }, 0) setImmediate(function D() { console.log(1); }); setImmediate(function D() { console.log(2); }); setImmediate(function D() { console.log(3); }); setTimeout(function timeout() { console.log('TIMEOUT-1 FIRED'); }, 0) setTimeout(function timeout() { console.log('TIMEOUT-2 FIRED'); }, 0) 

输出:

 TIMEOUT-1 FIRED
 TIMEOUT-2 FIRED
 TIMEOUT-1 FIRED
 TIMEOUT-2 FIRED
 1
 2
 3

让我们写上面的例子如下:

 var fs = require('fs') fs.readFile("readme.txt", function (){ setTimeout(function timeout() { console.log('TIMEOUT-1 FIRED'); }, 0) setTimeout(function timeout() { console.log('TIMEOUT-2 FIRED'); }, 0) setImmediate(function D() { console.log(1); }); setImmediate(function D() { console.log(2); }); setImmediate(function D() { console.log(3); }); setTimeout(function timeout() { console.log('TIMEOUT-1 FIRED'); }, 0) setTimeout(function timeout() { console.log('TIMEOUT-2 FIRED'); }, 0)}) 

输出:

 1 2 3 TIMEOUT-1 FIRED TIMEOUT-2 FIRED TIMEOUT-1 FIRED TIMEOUT-2 FIRED 

说明:

定时器的执行顺序取决于调用的上下文。 如果两者都是在主模块内部调用的,那么时序将受到进程性能的限制(可能受到在机器上运行的其他应用程序的影响)。 例如,如果我们运行以下不在I / O周期(即主模块)内的脚本,则两个定时器的执行顺序是非确定性的,因为它受过程执行的约束:

 // timeout_vs_immediate.js setTimeout(function timeout () { console.log('timeout'); },0); setImmediate(function immediate () { console.log('immediate'); }); $ node timeout_vs_immediate.js timeout immediate $ node timeout_vs_immediate.js immediate timeout 

但是,如果在I / O周期内移动这两个调用,则立即执行callback:

 // timeout_vs_immediate.js var fs = require('fs') fs.readFile(__filename, () => { setTimeout(() => { console.log('timeout') }, 0) setImmediate(() => { console.log('immediate') }) }) $ node timeout_vs_immediate.js immediate timeout $ node timeout_vs_immediate.js immediate timeout 

使用setImmediate()超过setTimeout()的主要优点是setImmediate()将始终在任何定时器之前执行(如果在I / O周期内进行调度),而与定时器的数量无关。

有关更多信息,请参阅以下链接: https : //github.com/nodejs/node/blob/master/doc/topics/the-event-loop-timers-and-nexttick.md