Harnessing the Magic of Non-Blocking Operations for High-Performing Node.js Applications

By Chauhanshubhankar — “Sorcerer Scripter


Every JavaScript developer deals with the event loop in some way or another, but it can be difficult to understand at first. To help you understand the significance of the event loop in Node.js, we will dive deep into its workings, discuss its implementation, and provide practical examples.

Now , what is an event loop and why do we have to understand it.?

Javascript is a single-threaded language; it runs on the browser’s main thread by default. Only one task can run at a time. Usually, it’s no big deal, but now imagine you’re running a task that takes 30 seconds. Yup During that task, we have to wait for 30 seconds before anything else can happen. It’s 2023 and no one wants slow and unresponsive websites.

In Node.js, the event loop is a single-threaded mechanism that allows for handling multiple operations concurrently. It enables non-blocking I/O operations, which means that while one operation is waiting for I/O (such as reading from a file or making an HTTP request), the event loop can switch to execute other tasks, thus maximising efficiency.

1. V8 Engine: Node.js utilises the V8 JavaScript engine developed by Google. V8 is responsible for executing JavaScript code and provides features like just-in-time (JIT) compilation, garbage collection, and memory management.

2. libuv: libuv is a library that provides an abstraction layer for handling asynchronous I/O operations and managing system resources. It is developed in the C language.

Event Loop:

The event loop is the central component responsible for managing and executing asynchronous operations. It runs on a single thread and continuously iterates through a set of phases while processing events and callbacks.

Fortunately, web browsers offer additional functionalities through a feature called the Web API, which goes beyond what the JavaScript engine alone provides. This Web API includes features like the DOM API (manipulating web page elements), setTimeout (delaying tasks), making HTTP requests, and more. These capabilities enable us to create asynchronous functions, allowing for more efficient and interactive web applications. It’s an exciting advantage!

Whenever we invoke a function, it gets added to the call stack. It is a part of the Javascript engine, and its stack means first in, first out.” When a function returns a value, it gets popped off the stack.

The respond function returns a setTimeout function, which is part of the Web API provided by web browsers. This function allows us to introduce a delay in executing tasks without blocking the main thread. We passed an arrow function () => { return ‘Hey’ } as a callback to the setTimeout function. This callback function is added to the Web API.

Afterwards, both the setTimeout function and the respond function are removed from the call stack since they have completed their tasks and returned their values.

In the Web API, a timer is set to run for the duration specified as the second argument, which in this case is 1000ms (1 second). However, the callback function is not immediately added to the call stack. Instead, it is placed in a queue, known as the task queue.

Now is the moment for the event loop to perform its primary duty of linking the queue with the call stack! When the call stack is devoid of any functions, indicating that all previously executed functions have completed and been removed from the stack, the first item in the queue is placed onto the call stack. In this scenario, no other functions were called, resulting in an empty call stack when the callback function became the initial item in the queue.

The event loop looks at the callback queue and the call stack. If the call stack is empty it pushes the first item in the queue onto the stack.

Now it’s clear how the event loop works but it will be good if we understand this over and over .
Let’s understand this again with an example.

const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"), 500);
const baz = () => console.log("Third");
bar();
foo();
baz();

Let’s quickly take a look at what’s happening when we’re running this code in a browser

  1. We invoke the bar() and . bar() return the settimeout() .
  2. The callback function we passed get added to the WEB API , the settimeout() and bar() get popped off the call stack.
  3. The timer runs and in meantime foo() gets invoked and logs the entry first , but foo() returns {= undefined } ,baz() gets invoked and the callback gets added to the Queue.
  4. Now baz() logs “third”. The event loop sees the call stack is empty after baz() returns. After which the callback gets added to the call stack . the callback logs the “second”.

Reference:


Meet The Team !!

Author: Chauhanshubhankar

Reviewed By: Rajkumar Selvaraju

Editor: Seema Jain


We at CaratLane are solving some of the most intriguing challenges to make our mark in the relatively uncharted omnichannel jewellery industry. If you are interested in tackling such obstacles, feel free to drop your updated resume/CV to careers@caratlane.com!