The event loop in Node.js is a mechanism that allows asynchronous tasks to be handled efficiently without blocking the execution of other operations.
Executes JavaScript synchronously first and then processes asynchronous operations.
Delegates heavy tasks like I/O operations, timers, and network requests to the libuv library.
Ensures smooth execution of multiple operations by queuing and scheduling callbacks efficiently.
Importance of Event Loop
The Event Loop is essential in Node.js because it allows non-blocking, asynchronous operations to be handled efficiently, even though Node.js operates on a single thread.
It allows non-blocking execution despite Node.js being single-threaded.
It helps handle I/O-bound tasks efficiently.
It makes Node.js suitable for scalable applications like web servers.
The first statement is logged immediately.
setTimeout schedules the second statement to log after 1000 milliseconds.
The third statement is logged immediately after.
After 1000 milliseconds, the callback from setTimeout is executed, logging Second statement.
When a Node.js application runs, the event loop starts, processes the synchronous code first, and then moves to handle asynchronous tasks. The execution follows these steps:
When Node.js starts, it loads the script, executes synchronous code, and registers any asynchronous tasks (e.g., timers, I/O requests, network operations).
2. Execution of Input Script
The call stack executes synchronous code first.
Any asynchronous operations (setTimeout, fs.readFile, network requests) are delegated to libuv.
3. Handles Asynchronous Operations with libuv
Node.js uses the libuv C library to manage asynchronous operations. It maintains a thread pool to handle heavy tasks like file I/O and network requests without blocking the event loop.
File system I/O (fs.readFile)
Network requests (HTTP, TCP, DNS)
Timers (setTimeout, setInterval)
Compression and cryptographic tasks
4. Callback Execution
Once the thread pool completes its tasks, it sends callbacks to the event queue. The event loop processes these callbacks, but only when the call stack is empty (i.e., when no synchronous code is currently executing).
5. Event Loop Phases
The event loop goes through multiple phases, each designed to handle a different set of operations. It checks for events, handles asynchronous callbacks, and executes tasks in the correct order.
6. Callback Execution from Event Queue
After the call stack is empty, the event loop picks tasks from the event queue and sends them to the call stack for execution. These tasks could include:
Completing network requests
Processing I/O events
Handling timers like setTimeout or setInterval
Phases of the Event loop
The event loop in Node.js consists of several phases, each of which performs a specific task. These phases include:
This phase executes callbacks for closed connections like sockets, streams, and event emitters.
The server listens for incoming connections.
When a socket is closed, the 'close' event is emitted, and the corresponding callback is executed in the close callbacks phase.
Output:
Server listening on port 8000
process.nextTick() and Promises in the Event Loop
Apart from these phases there is also process.nextTick() and promise callback which has the highest priority in the event loop. It executes after every phase before moving to the next phase.
process.nextTick() callbacks are always executed before the event loop moves to the next phase.
Resolved Promise callbacks are processed immediately after process.nextTick().