met*_*tis 7 javascript node.js
在nodejs的官方网站(https://nodejs.org/api/timers.html#timers_setimmediate_callback_arg)中,据说:
setImmediate()函数在I/O事件的回调之后和触发setTimeout和setInterval设置的定时器之前调度"立即"执行回调.
但是在下面的代码中,setTimem()函数在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)
Run Code Online (Sandbox Code Playgroud)
结果:
TIMEOUT FIRED 1 4 2 3 5 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)
Run Code Online (Sandbox Code Playgroud)
输出:
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)})
Run Code Online (Sandbox Code Playgroud)
输出 :
1
2
3
TIMEOUT-1 FIRED
TIMEOUT-2 FIRED
TIMEOUT-1 FIRED
TIMEOUT-2 FIRED
Run Code Online (Sandbox Code Playgroud)
解释 :
定时器的执行顺序将根据调用它们的上下文而变化。如果两者都是从主模块内部调用的,那么计时将受到进程性能的约束(这可能会受到计算机上运行的其他应用程序的影响)。 例如,如果我们运行以下不在 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
Run Code Online (Sandbox Code Playgroud)
但是,如果在一个 I/O 周期内移动这两个调用,则始终先执行立即回调:
// 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
Run Code Online (Sandbox Code Playgroud)
使用 setImmediate() 相对于 setTimeout() 的主要优点是,如果在 I/O 周期内调度,setImmediate() 将始终在任何计时器之前执行,而与存在多少个计时器无关。
有关更多信息,请参阅以下链接: https://github.com/nodejs/node/blob/master/doc/topics/the-event-loop-timers-and-nexttick.md