We have all heard about JavaScript and Node.js being single-threaded, but what does it mean in practical terms?
It means that JavaScript can do on...
For further actions, you may consider blocking this person and/or reporting abuse
For anyone interested, I gave a conference talk on this a couple months ago: https://www.youtube.com/watch?v=KKM_4-uQpow&ab_channel=UtahJS
It's "A Deep Dive into the Node.js Event Loop", complete with tons of code examples so you can see these concepts in action. Here's the GitHub repo as well: github.com/thawkin3/nodejs-event-l...
Woh Tyler, Your explanation about the topic is one of the best i ever heard, You helped me put together two important concepts that are the task queue and the phases, Thank you Tyler.
Thanks Bento! That's very kind of you.
it is great explanation. thanks man
Amazing Talk. Thank you Tyler.
Thanks Debajyoti! Glad you liked it.
How does nodejs know which task should be handled by libuv ?
Not an exhaustive list:
Redacted on 8/11/2023
It's not even close to how it actually works. There's no "event queue" (or in other words there are multiple and not exactly queues). "the event loop" has no relation to Node, it's libuv thing, the only relation is that
libuv
was extracted from early version of Node,process.nextTick
never reaches "the event loop" (the one in libuv), Node doesn't run anything in it's single thread while libuv is busy with the query. If it is a single query and there are not timers andsetImmediate
-s then the whole thing will be blocked onepoll
in linux case waiting on that query to return. If there are timeouts then it'll poll thatepoll
with timeout of0
and move onto timeouts.Go to libuv, look at file operations API and compare it to Node's file operation API.
For demonstration purposes I wrote a very simple and primitive http server using raw
libuv
- github.com/tnymlr/hello-libuv/blob...Node does very similar thing with the difference that it's running V8 in those handlers.
You JS code runs in libuv handlers with the exception of the entry file, the entry file runs before the event loop has even started.
Thank you for your valuable feedback. It is a simplified version of this complex mechanism and we couldn't capture all the details as you mentioned. Would you like to connect on Twitter to improve the animations?
Thanks sir.
hi the last image in this article is being broken, could you please fix it!
Does it mean that Promises, timeouts and intervals are handled differently under the hood in browser and nodejs?
Chrome uses
libevent
for the event loop, but promises, timeouts, and intervals are processed in the same order in the two environments.Some things are available in node but not in browser. Ex.setImmediate. This shows that there are differences (even though there are many similarities).
As you know a task can be either asynchronous (non blocking) or synchronous (blocking) so for any task of asynchronous type nodejs pushes it to be handled by libuv and continue executing other synchronous tasks.
Is it true? I hear in some where, asynchronous is talk to non-blocking operations and vice versa synchronous is blocking operations or I'm wrong.
Yes you are correct..updated the comment.
Great article, learned a few things 👍✨💯
Does Node works like this:
I've learned how javascript works in background, with example of GEC (Global Execution Context),
Call stack is populated with GEC:
1) console.log("Starting Node js"),
2) db.query()...
3) console.log("Before query results")
Call stack is populated with GEC (this means we cannot handle async code) till we reached console.log("Before query results").
In this animation call stack is populated line by line, and it's empty after each line, for example if we have setTimeout function with 0ms instead of query as 2nd line, even it's async operation it would execute first, before second console.log because call stack is empty after each line.
Well done!
Helpful and interesting to read! Thanks!
Thank you for explaining this, it helped me understand far more than other explanations in the past. Appreciate it.
Very well explained, rich in details. Thanks @fabriziolallo and @andrewhu368
Thanks a bunch!!! 🫶🏻
I have learned many things from this article. Thank you.
Nice!
Hey bro,
Loved the way you explained using GIFs.
Could you please share what tool you used to generate these GIFs?
Keynote on Mac
Thanks Bro!
Great animation to explain the concept! Kudos 🎉🎉
Thank you so much for the best article!
It really impressive, but I have a little confusion which I need to get it's clear picture!
Callstack is stack and we have queue , which data structure do WEB APIs use to keep track of asynchronous tasks?
Which tool do you use to make animation?
How does libuv process promises ?
Does it create seperate thread for each promise ?
What exactly takes place during promise resolution?
How are instructions of promise resolution executed?
Could you please explain.
Thanks ...
Node is single-threaded, there is no way to run multiple threads (though i/o is multithreaded). Any call made runs unless "paused-until-resumed". Bad thing you can do is to run long-lasting "for" loop without "pause" because then node cannot do anything until your loop is finished. I can often see this problem when connection to a server (DB, queue, Kafka, etc.) is killed as not responding to health check - because long loop is running.
When you "paused-until-resumed" then node (or any similar engine) runs other tasks (ex. response to health check). It will be back to your paused-promise when done with other tasks.
I have published an post (probably not yet finished) about that: dev.to/adderek/asynchronous-proces...
Thanks @fabriziolallo for sharing animated guide for Node.js in detail.
Awesome explanation ✨
Now I really know how this works. Thank you very much. I really appreaciate it. Very informative and also using visuals to really show its flow, which is very intuitive.
Great explanation with graphics and narrowed scope. Love it
Once db.query is sent to libuv how does it manage the connection to the database and does it use the 4 threads in the threadpool. If there are of slow I/O (http reqeuest to another service or db calls) how is that manged in libuv?
Every OS supports different types of async I/O (file, networking, etc..), and Libuv provides an abstraction layer over different I/O OS implementations.
So under the hood Libuv simply use the networking I/O implemented by the OS to connect to the database server. Threadpool is used for complex and high intensive CPU I/O types in order not to block the Event Loop. So, tasks like DNS lookup, crypto functions and others, are executed in the threadpool.
greattttt
Thanks for providing the beautiful animation
latentflip.com/loupe
For people who want to see all these in action with your own code.
This tool is for browser event loop but ideas are identical.
Pretty crazy stuff if you ask me.
Cna you explain async await?
libuv is a C library not C++ library
great work
Thanks, the event loop animated pretty well. I'll reference the idea. I might reference to your post with whose imagine the event loop in NodeJs.
Thanks