DEV Community

Cover image for Node.js animated: Event Loop

Node.js animated: Event Loop

Andrew Hu on November 05, 2022

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...
Collapse
 
thawkin3 profile image
Tyler Hawkins

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...

Collapse
 
ariannexux profile image
Bento Julio

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.

Collapse
 
thawkin3 profile image
Tyler Hawkins

Thanks Bento! That's very kind of you.

Collapse
 
yosef_aweke_4537bcc49cd90 profile image
Yosef Aweke

it is great explanation. thanks man

Collapse
 
debajyotix profile image
Debajyoti Majumder

Amazing Talk. Thank you Tyler.

Collapse
 
thawkin3 profile image
Tyler Hawkins

Thanks Debajyoti! Glad you liked it.

Collapse
 
deepak22448 profile image
Deepak Sharma

How does nodejs know which task should be handled by libuv ?

Collapse
 
andrewhu368 profile image
Andrew Hu • Edited

Not an exhaustive list:

  • I/O requests (network requests, file system operations, etc.)
  • setTimeout, setImmediate, setInterval,
  • close callbacks (e.g. socket.on('close', () => {})

Redacted on 8/11/2023

Collapse
 
tmlr profile image
Tony Miller

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 and setImmediate-s then the whole thing will be blocked on epoll in linux case waiting on that query to return. If there are timeouts then it'll poll that epoll with timeout of 0 and move onto timeouts.

Go to libuv, look at file operations API and compare it to Node's file operation API.

Thread Thread
 
tmlr profile image
Tony Miller

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.

Thread Thread
 
andrewhu368 profile image
Andrew Hu • Edited

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?

Collapse
 
deepak22448 profile image
Deepak Sharma

Thanks sir.

Collapse
 
hcminhit profile image
i love Math

hi the last image in this article is being broken, could you please fix it!

Collapse
 
andrewhalych profile image
Andrew Halych

Does it mean that Promises, timeouts and intervals are handled differently under the hood in browser and nodejs?

Thread Thread
 
andrewhu368 profile image
Andrew Hu

Chrome uses libevent for the event loop, but promises, timeouts, and intervals are processed in the same order in the two environments.

Thread Thread
 
adderek profile image
Maciej Wakuła

Some things are available in node but not in browser. Ex.setImmediate. This shows that there are differences (even though there are many similarities).

Collapse
 
animeshsri98 profile image
Animesh Srivastava • Edited

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.

Collapse
 
aydafield22 profile image
aydafield22

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.

Thread Thread
 
animeshsri98 profile image
Animesh Srivastava

Yes you are correct..updated the comment.

Collapse
 
madza profile image
Madza

Great article, learned a few things 👍✨💯

Collapse
 
rimla1 profile image
Almir Muminovic

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.

Collapse
 
bobbyiliev profile image
Bobby Iliev

Well done!

Collapse
 
dhruvjoshi9 profile image
Dhruv Joshi

Helpful and interesting to read! Thanks!

Collapse
 
peterwitham profile image
Peter Witham

Thank you for explaining this, it helped me understand far more than other explanations in the past. Appreciate it.

Collapse
 
juberjj profile image
Juber Nunes

Very well explained, rich in details. Thanks @fabriziolallo and @andrewhu368

Collapse
 
ashm10 profile image
Asther Marie Moreno

Thanks a bunch!!! 🫶🏻

Collapse
 
jinacker profile image
jinacker

I have learned many things from this article. Thank you.

Collapse
 
guscarpim profile image
Gustavo Scarpim

Nice!

Collapse
 
nandhakumar profile image
Nandhakumar

Hey bro,
Loved the way you explained using GIFs.

Could you please share what tool you used to generate these GIFs?

Collapse
 
andrewhu368 profile image
Andrew Hu

Keynote on Mac

Collapse
 
nandhakumar profile image
Nandhakumar

Thanks Bro!

Collapse
 
raibtoffoletto profile image
Raí B. Toffoletto

Great animation to explain the concept! Kudos 🎉🎉

Collapse
 
peninah98 profile image
peninah98

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?

Collapse
 
jack_wang profile image
炽翎

Which tool do you use to make animation?

Collapse
 
guwahati_iiit profile image
IIIT Guwahati Student

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 ...

Collapse
 
adderek profile image
Maciej Wakuła • Edited

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...

Collapse
 
sanjay_pasari profile image
Sanjay Pasari

Thanks @fabriziolallo for sharing animated guide for Node.js in detail.

Collapse
 
varshithvhegde profile image
Varshith V Hegde

Awesome explanation ✨

Collapse
 
solonbryan50 profile image
Bryan Solon

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.

Collapse
 
adderek profile image
Maciej Wakuła

Great explanation with graphics and narrowed scope. Love it

Collapse
 
tkumark profile image
tkumark

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?

Collapse
 
fabriziolallo profile image
Fabrizio Lallo

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.

Collapse
 
arjinalbay profile image
Arjin

greattttt

Collapse
 
bhanukiranmaddela profile image
bhanukiranmaddela

Thanks for providing the beautiful animation

Collapse
 
fantasycheese profile image
Fantasycheese • Edited

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.

Collapse
 
yourex69 profile image
Shubhankarsingh124

Cna you explain async await?

Collapse
 
epiloguess profile image
epiloguess

libuv is a C library not C++ library
Image description

Collapse
 
hicham_hal profile image
Hicham

great work

Collapse
 
aoftionstyle profile image
Chutipon Pongpanit

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.

Collapse
 
nandansn profile image
Nandakumar R

Thanks