为什么Node.js libuv线程池执行不是并发的?

Why Node.js libuv thread pool execution is not concurrently?

AFAIK Node.js 异步任务被调度到引擎盖下的 libuv,并且 libuv 有一个线程池,默认情况下有 4 个线程。 我测试下面的代码:

setImmediate(() => {
    sleep(1000 * 3);
    console.log('a');
});

setImmediate(() => {
    sleep(1000 * 3);
    console.log('b');
});

setImmediate(() => {
    sleep(1000 * 3);
    console.log('c');
});

function sleep(time) {
    let start = new Date().getTime();
    while (new Date().getTime() - start < time) {
    }
}

我认为发送到libuv的3个任务会并发执行,输出a/b/c应该几乎同时打印,但实际上这三个输出每3秒出现一次。 哪里错了? 谢谢。

AFAIK Node.js asynchronous task is dispatched to the libuv under the hood, and the libuv has a thread pool, 4 threads is in the pool by default. I test the code below:

虽然不完全错误,但也不正确。默认情况下不使用线程池。线程池仅用于同步、阻塞 IO 任务,如文件 IO 和 DNS 查找。这些任务的回调将再次入队到 JS 线程。

Libuv 定时器只使用一个普通的定时器队列。简而言之,每次您创建一个新计时器时,库都会检查它必须等待的最短时间,等待,然后遍历所有计时器,更新它们并触发已过期计时器的回调。然后它 returns 进入第一步并检查它必须等待的最短时间。

您可以创建数百万个计时器,它们都可以使用同一个线程。他们不需要 运行 的线程池。

您的程序按预期运行。回调会立即排队到主 JS 线程,并且每个回调都忙等待 3 秒,然后打印一些值并继续前进。在这种情况下,甚至没有开始的计时器。我很确定 setImmediate 只是将任务排到事件循环队列的末尾。