I’ve been testing some code to see how does NodeJS event loop actually works. So I get in touch with this piece of code:
console.time('Time spending');
let list = [];
for (let index = 0; index < 1000000; index++) {
const data = JSON.stringify({
id: Date.now(),
index,
});
list.push(data);
}
console.log(list);
console.timeEnd('Time spending');
When this code is executed, NodeJS spawns eleven threads on SO (Ubuntu running on WSL 2). But why it does that?
This code is not being declared as an async code.
2
Answers
That’s the worker pool. As mentioned in the great guide Don’t block the event loop, Node.js has an "event loop" and a worker pool. Those threads you see are the worker pool, and the size is defined with the environment variable UV_THREADPOOL_SIZE, from libuv, which Node.js uses internally. The reason
node.js
spawns those threads has nothing to do with your expensive loop, it’s just the default behavior at startup.There’s extensive documentation on how the event loop works on the official Node.js site, but essentially some operations, like filesystem I/O, are synchronous because the underlying operating system does not offer an asynchronous interface (or it’s too new/experimental). Node.js works around that by using a thread pool where the event loop submits a task, like reading a file, which is usually a synchronous job, and goes to the next event while a thread does the dirty work of actually reading the file, it can block the thread, but it does not matter, because the event loop is not blocked. When it’s done, it reaches back to the event loop with the data. So, for the event loop (and the programmer), the synchronous read was done asynchronously.
There are no parallel threads being used to run your code. Nodejs runs all your code you show in just one thread. You could just do this:
And, you would see the same number of threads. What you are seeing has nothing to do with your specific code.
The other threads you see are just other threads that nodejs uses for it’s own internal purposes such as the worker pool for disk I/O, asynchronous crypto, some other built-in operations and other internal housekeeping operations.
Also, Javascript code marked as
async
still runs in the one main Javascript thread so your reference that nothing isasync
wouldn’t change things either. It doesn’t matter (from a thread point of view) whether code isasync
or not.Your big
for
loop blocks the entire event loop so no other Javascript code or events can run until yourfor
loop finishes. There’s no really much to learn about the event loop from this code except that your loop blocks the event loop until the loop completes.