AFAIK Node.js asynchronous task is dispatched to the libuv under the hood, and the libuv has a thread pool, 4 threads are in the pool by default. I test the code below:
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) {
}
}
I think the 3 task send to the libuv will execute concurrently, and the output a / b / c should print almost at the same time, but in fact, the three outputs appear every 3 seconds. Where is wrong? thanks.
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:
Althought not entirely wrong, it's not correct either. the threadpool is not used by default. the threadpool is only used for synchronous, blocking IO tasks like File IO and DNS lookup. the callback of these tasks will be enqueue again to the JS thread.
Libuv timers just use an ordinary timer-queue. In a nutshell , every time you create a new timer, the library checks for the minimum time it has to wait, waits, then iterates over all of the timers, updates them and fires callbacks of timers that were expired. then it returns to step one and checks the minimum time it has to wait.
You can create millions of timers, and they all can use the same thread. they don't need a threadpool to run.
Your program behaves as expected. the callbacks are enqueued immediately to the main JS thread, and each of them busy-waits for 3 seconds before printing some value and moving on. in this case, there isn't even a timer to begin with. I'm pretty sure setImmediate
simply enqueues a task to the end of the event-loop queue.