January 25, 2024
JavaScript is a single-threaded language that executes the code synchronously. A single call stack is used to execute the JavaScript code which follows FILO ( first in last out) principle. A piece of code enters the call stack end and exits once the code is executed. This makes JavaScript a single-threaded language as a single call stack is used.
In this article, we are going to explore how JavaScript handles asynchronous operations using an event loop.
Before we dive into synchronous code, let us understand what we actually mean when we say JavaScript is synchronous.
Consider the following code snippet
console.log("Starting...");
for (i = 10 ;i > 5; i--){
console.log("Value of i: ", i)
}
console.log("Finished!")In the above code, we are using a for loop which iterates through the value of i . The for loop is acting as a blocking code that blocks the execution of the console statement beneath it. Once for loop is completed, only then the console statement is executed. The output of the above code looks like this:

All the code is executed in a sequence. The JavaScript interpreter executes the code line by line and pushes it into the call stack. Once the code is executed, it is popped off from the call stack.
Now let’s understand asynchronous operations in JavaScript. As Javascript is a single-threaded language, it performs one operation at a time. But we can make JavaScript perform more than one operation using APIs provided by the browser or Node.js.
console.log("Starting...");
setTimeout(()=>{
for (i = 10 ;i > 5; i--){
console.log("value of i: ", i)
}
},1000)
console.log("Finished!")We have slightly changed the implementation of the code which we used in the synchronous section. We have implemented setTimeout which is an API provided by the browser. This API takes a callback, which is to be called later, as the first parameter and a delay, the duration after which the callback function is to be executed, as the second parameter.
Let’s dive deep into exactly how this code is executed by the JavaScript engine.

When JavaScript is executed inside the browser, there exists a JS engine that is responsible for executing the JS code. The browser provides some APIs that are being used by JavaScript to manipulate the DOM, make network requests, manage client-side storage, etc. When the code is executed, a global execution context is created. You can read more about the global execution context here.
In our example, we are using setTimeout which is being provided by either a browser or Node.js. When the first line i.e., console statement, is executed, it is pushed into the call stack.

When the console statement is executed, it is popped off from the call stack. The next code is then scheduled to be pushed into the call stack, but in our case, we are using setTimeout which part ways from the main JavaScript execution thread.
As the setTimeout is pushed into another thread, the JS engine moves onto the last line where it prints the statement to the console.
The execution of setTimeout takes a slightly different approach in the JS engine. The setTimeout takes a callback function which is to be executed later after some time. JS engine registers the callback function along with the time. When the specified time is passed, the registered callback is then scheduled to be pushed into the call stack. But the callback function cannot be directly pushed into the call stack. Instead, the callback function is pushed into the callback queue. A callback queue is a queue data structure that holds all the callbacks which are to be pushed into the call stack.

When the callback function is pushed into the callback queue, it is time for it to be pushed into the call stack. Here comes event loop into the action. An event loop checks if there are any callbacks present in the callback queue and if so, they are pushed into the call stack.

The callback function is pushed into the call stack where it is executed and then vanished from the call stack. When all the code is executed, the global execution context created earlier is destroyed.
This article shows how asynchronous code is handled in the JS engine using callback queues and event loop. If you have any queries, let me know in the comment section.
Happy coding !!!