相关疑难解决方法(0)

NodeJS - setTimeout(fn,0)vs setImmediate(fn)

这两者有什么区别,我什么时候才能使用另一个?

javascript node.js

72
推荐指数
3
解决办法
3万
查看次数

setTimeout和setImmediate之间的优先级

我在节点文档中读到了这个:

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)

javascript node.js

9
推荐指数
1
解决办法
1125
查看次数

CommonJS 与 ESM 中 setImmediate() 和 setTimeout() 回调的优先级

如果使用 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 模块异步加载有关吗?

javascript event-loop commonjs node.js es6-modules

8
推荐指数
1
解决办法
425
查看次数

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

在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)

javascript node.js

7
推荐指数
1
解决办法
659
查看次数

为什么在主模块中使用setTimeout(0)和setImmediate()的行为未定义?

采取以下来自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因此,当都可用时,这会导致竞争状态,因此输出将是不确定的。

这是对的吗 ?还是有其他原因导致不确定性?

event-loop race-condition node.js

5
推荐指数
1
解决办法
303
查看次数