Node.js 中的 Multiple setTimeout 执行是单线程还是多线程?

is Multiple setTimeout execution single threaded or mutli threaded in Node.js?

假设我有 3 个 setTimeout,如下所示:

console.log(new Date().toLocaleTimeString());

setTimeout(() => { console.log(new Date().toLocaleTimeString()); }, 3000);

setTimeout(() => { console.log(new Date().toLocaleTimeString()); }, 6000);

setTimeout(() => { console.log(new Date().toLocaleTimeString()); }, 9000);

由于Node是单线程的,每次超时应该一个接一个的执行。因此输出应该如下所示:

9 am 0s (intial)

9 am 3s(+3s)

9 am 9s(+6s)

9 am 18s(+9s)

但我发现的是:

9 am 0s (initial)

9 am 3s(+3s)

9 am 6s(+3s)

9 am 9s(+3s)

所以很明显所有超时都同时开始了。每个超时之间的差异被添加到每个超时之间,在这种情况下是+3s,

在这种情况下,这会使 nodejs 成为多线程吗?我知道并非节点 运行 的所有部分都在同一个线程中,而且很少有人在同一个线程外执行。

有人可以让我更好地理解这一点。或者我的做法不对。

Since Node is single threaded, execution of each timeout should be one after the other.

Node.js 不是单线程的。但默认情况下它会 运行 一个 JavaScript 线程。您可以通过 worker_threads module 运行 其他人。 (每个工人都有自己的 JavaScript 环境;他们可以交流。)

Hence the output should be as expected as below:

不,不应该。您的代码正在启动三个计时器 一个接一个 。对 setTimeout 的所有三个调用都立即 运行,启动它们的计时器。然后事件循环继续,等待做某事,大约三秒后,它看到第一个计时器回调的时间到了,所以它 运行 进行了回调。然后事件循环继续。大约三秒后(总共六秒),它发现是时候进行第二次回调了,于是就这样做了。循环继续……三秒后,它进行第三次回调。这一切都在一个线程上。

在 Node.js here 中有更多关于事件循环的内容。

Node 的事件循环与浏览器的类似。这是浏览器中的示例,带有一些额外的日志记录:

const start = Date.now();

function elapsedPrefix() {
    return ("+" + (Date.now() - start)).padStart(4, " ");
}

function log(...msgs) {
    console.log(`${elapsedPrefix()}: ${msgs.join(" ")}`);
}

function now() {
    return new Date().toISOString().substring(11, 12);
}

function startTimeout(num, fn, ms) {
    log(`Start timer ${num} for ${ms}ms`);
    setTimeout(() => {
        log(`Timer ${num} firing`);
        fn();
    }, ms);
}

log(`Starting timers`);

startTimeout(1, () => { log(new Date().toLocaleTimeString()); }, 3000);
startTimeout(2, () => { log(new Date().toLocaleTimeString()); }, 6000);
startTimeout(3, () => { log(new Date().toLocaleTimeString()); }, 9000);

log(`Timers started`);