本文介绍了为什么在主模块中使用时 setTimeout(0) 和 setImmediate() 的行为未定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

nodejs 事件循环中获取以下代码文档:

// timeout_vs_immediate.js
setTimeout(() => {
  console.log('timeout');
}, 0);

setImmediate(() => {
  console.log('immediate');
});

根据文档:

例如,如果我们运行以下不在 I/O 中的脚本循环(即主模块),两个定时器的顺序执行是不确定的,因为它受过程.

为什么上面的说法是正确的?是不是因为 nodejs 运行时实际上使用了多个线程来挑选必须执行的回调.

Why is the above statement true ? Is it because the nodejs runtime actually employs more than one thread to pick out the callbacks that have to be executed.

我的直觉是:有两个线程为 setTimeoutsetImmediate 执行回调,所以当它们都可用时,这会导致竞争条件,因此输出将是不确定的.

What my intuition says: there are two threads that execute callbacks for setTimeout and setImmediate so when both of them are available this leads to a race condition, and thus the output will be non-deterministic.

正确吗?或者是否有其他原因导致这是不确定的?

Is it correct ? Or is there any other reason for which this is non-deterministic ?

推荐答案

本质上,发生了两件事:

Essentially, two things happen:

  1. setTimer(0..) 被转换成 setTimer(1..)
  2. 在(下一个)事件循环开始之前,node/libuv 必须执行clock_gettime() 以从系统获取当前时间.此系统调用所用的时间是不确定的,因为它取决于当时的系统负载.现在,如果 clock_gettime() 花费的时间超过 1ms,则 setTimer 回调将运行 (#),否则事件循环将继续到下一阶段 (##).

  1. setTimer(0..) gets converted into setTimer(1..)
  2. before the (next) event loop tick begins, node/libuv has to perform a clock_gettime() to get the current time from the system. The time taken for this system call is non deterministic as it depends on the system load at that time. Now, if clock_gettime() took more than 1ms, the setTimer callback will run (#), else event loop continues to next phase (##).

  • 如果 (#),setTimeout(0,..) 回调在 setImmediate() 之前运行
  • 如果 (##),则不然.

参考:https://github.com/nodejs/help/issues/392#issuecomment-305969168

这篇关于为什么在主模块中使用时 setTimeout(0) 和 setImmediate() 的行为未定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 17:14