这两者有什么区别,我什么时候才能使用另一个?
我在节点文档中读到了这个:
setImmediate(callback,[arg],[...])
在I/O事件回调之后以及之前
setTimeout和之后安排"立即"执行回调setInterval
但是,我看到相反的情况.
setTimeout之前执行setImmediate.是否有人对此行为进行了解释,或者有关于节点事件循环的任何文档?
谢谢 :)
代码:
var index = 0;
function test(name) {
console.log((index++) + " " + name);
}
setImmediate(function() {
test("setImmediate");
})
setTimeout(function() {
test("setTimeout");
}, 0);
process.nextTick(function() {
test("nextTick");
})
test("directCall");
Run Code Online (Sandbox Code Playgroud)
输出:
0 directCall
1 nextTick
2 setTimeout
3 setImmediate
Run Code Online (Sandbox Code Playgroud) 如果使用 CommonJS 模块,使用 setImmediate 调用 setTimeout 会出现不可预测的行为。但如果切换到ESM(package.json中的“type”:“module”),它总是会在setTimeout之前执行setImmediate。
setTimeout(() => {
console.log('timeout');
}, 0);
setImmediate(() => {
console.log('immediate');
});
Run Code Online (Sandbox Code Playgroud)
为什么会出现这种情况?这与 ESM 模块异步加载有关吗?
在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 …Run Code Online (Sandbox Code Playgroud) 采取以下来自nodejs事件循环文档的代码:
// timeout_vs_immediate.js
setTimeout(() => {
console.log('timeout');
}, 0);
setImmediate(() => {
console.log('immediate');
});
Run Code Online (Sandbox Code Playgroud)
根据文档:
例如,如果我们运行以下不在I / O周期(即主模块)内的脚本,则执行两个计时器的顺序是不确定的,因为它受进程性能的约束。
为什么上述说法是正确的?是因为nodejs运行时实际上使用了多个线程来挑选必须执行的回调。
我的直觉是什么:有两个线程为setTimeout和执行回调setImmediate因此,当都可用时,这会导致竞争状态,因此输出将是不确定的。
这是对的吗 ?还是有其他原因导致不确定性?