9 July 2023 4 min Read
event loopnodejsasync io
Introduction;
Nodejs is a Javascript Runtine environment ,it execute Javascript on a Blocking single thread. but what makes the popularity of Nodejs is it's approche for handling Asyncronous operation in an Non-blocking way ,operations like writing to disc , networking ect. The Piece of Software that allow nodejs to manage between synchronous and asynchronous operation is Called the Event Loop. Every Nodejs Developer needs to have a good understanding of these concepts in order to develop effeciant applications and avoid common performance issues. in this blog post we try to introduce generale understandings about the Nodejs Event Loop and Async IO, if you want to deep dive into Nodejs please check the further resource section.
What compose Nodejs environment
what we see in the illustration above is an abstract way to define the composition of nodejs ,we have :
-
V8 Engine: is the part that compile javascript into machine code and then execute it in a single thread meaning that all the operation will be execute sequencialy one By one, it uses a call stack to keep track of functions calls and mmanaging their execution .
-
Libuv: is a cross-platform library responsible for handling IO operations whether by calling OS handlers ,child process or using threads Pool whithout blocking the main thread . and abstracts the underlying operating system's file system, network, and concurrency capabilities. It handles tasks such as managing event loops, timers, file operations, networking, and threading. libuv allows Node.js to achieve non-blocking, event-driven behavior.
-
native C/C++ modules : modules like the 'http module' ,Dns resolver, bycrypt for Encryption and Zlib for compression etc.
The execution flow of execution :
let's get back to the illustration mentioned before, we have a server application written in Node js and we launch it's execution ,what's really happend:
V8 Engine will compile the js code into machine code, prepare the Heap and Call stack and then run execute the first operation.
if the operation is synchronous example like arithmetique operation it will be executed imediatly in the main thread and then getting to the next operation.
if it's Asynchronous operation like disc or network operation , Nodejs will not execute it in the main thread as it will block it but it will pass it to the LibUV and continue the execution to the next operation.
LibUV will launch the operation By using a thread worker, child process or OS handler and queued it's callback in the correspending Event Queue.
the Event loop will ensure the all the syncronous code will be executed first , then if the call stack is empty it will check for completed operations by invoking the registered callback functions.
when concurrent IO operation are ready to be executed , the event loop manage the priority between the callbacks
The Event loop Phases
as we disccus earlied the event loop is the piece of code responsible for handling asyncronous operation.it's activly checking Event queues.in the case of concurency the event loop follow this order of priority.
First, there is the timer queue , which holds callbacks associated with setTimeout and setInterval.
Second, there is the I/O queue which contains callbacks associated with all the async methods such as methods associated with the fs and http modules.
Third, there is the check queue which holds callbacks associated with the setImmediate function, which is specific to Node.
Fourth, there is the close queue which holds callbacks associated with the close event of an async task.
Finally, there is the microtask queue which contains two separate queues.
- nextTick queue which holds callbacks associated with the process.nextTick function.
- Promise queue which holds callbacks associated with the native Promise in JavaScript.
What to keep in Mind when developing Node js application
here is some points that i throught about regarding the event loop and asynchronous operation
Blocking the Event Loop:
-
always use Asynchronous API whenever it's possible : for example FS module that enable file operations on the OS provide both synchronous and asynchronous API,my go to is the async API unless you really knowing what you are doing
-
Avoid Performing Intensive CPU computing : as this will block other asynchronous operations ,it's better to overload it to another thread worker or spinning a child process to handle the computing.
Inefficient Resource Utilization:
perform intensive CPU computing will consume excessive CPU resources,leading to poor resource utilization. Instead, breaking the task into smaller.
Inadequate Concurrency Management:
Proper utilization of techniques like promises, async/await, and callback patterns can help manage concurrency effectively and avoid issues like race conditions or deadlocks. you have to Understand the priority and the order of execution of your asynchronous code is crutial espicially that node js is an event driven runtime.
Lack of Error Handling:
use error handling techniques such as try-catch blocks, error events, or promises' rejection handling , otherwise you'll end up with unhandled exceptions or silent failures that can be hard to trace.
Learn about the Best Practices in generale is required:
you have to learn when to use various technics that was designed to solve certain problem like caching technique, streams -based API ,clusting and so On
Further Resources
i have found this material helpful to learn more about the topic and i want to share it with you:
-
Everything You Need to Know About Node.js Event Loop - Bert Belder, IBM on youtube
-
Node's Event Loop From the Inside Out by Sam Roberts, IBM on youtube
-
Nodejs | Event loop,timer and Next tick Official Docs
-
What the heck is the event loop anyway | Philip Roberts | JSConf EU on youtube
-
Here's Why Node JS is NOT Single Threaded on youtube
-
The Node.js Event Loop: Not So Single Threaded on youtube
-
Don't Let Just Node.js Take the Blame! - Danial Khan on youtube
-
Event loop in JavaScript on AceMood's Blog
-
Event Loop and the Big Picture — NodeJS Event Loop By Deepal Jayasekara Meduim
-
LibUV Design LibUV official documentation
-
using libuv and http-parser to build a webserver vimeo