DEV Community

Cover image for Deep Dive into JavaScript Event Loop
Imran shaikh
Imran shaikh

Posted on

Deep Dive into JavaScript Event Loop

JavaScript is a single-threaded, non-blocking, asynchronous, concurrent language. Its concurrency model is heavily reliant on an entity known as the Event Loop. This blog post will provide a detailed exploration of the JavaScript Event Loop and how it handles asynchronous operations. We'll discuss the call stack, web APIs, the callback queue, the microtask queue, and async/await & promises.

  1. Call Stack

The call stack is a mechanism that JavaScript uses to track function execution. It's a LIFO (Last In, First Out) data structure - the last function that gets pushed into the stack is the first one to be popped out when its execution is complete. When a script calls a function, JavaScript pushes that function onto the call stack and starts executing it. Once it's done, JavaScript pops it off the stack and resumes execution where it left off in the code. If the stack takes up more space than it had assigned to it, it results in a "stack overflow."

  1. Web APIs

Web APIs are not provided by the JavaScript language itself, but by the browser environment. They are essentially a set of functions and objects that JavaScript can interact with, allowing it to perform operations like fetch data, manipulate the DOM, handle user events, etc. These operations are asynchronous, meaning they can occur outside the regular top-to-bottom flow of the JavaScript execution.

When a function with an asynchronous task (like a setTimeout or an AJAX call) is called, it gets pushed to the call stack, but then it's offloaded to the Web API. The Web API handles the task, allowing the call stack to continue executing other tasks without being blocked.

  1. Callback Queue

Once the Web API has completed the asynchronous task, it doesn't return the result to the call stack directly. Instead, it pushes the callback function (a function to be executed after the task is complete) to a Callback Queue. The Callback Queue is a FIFO (First In, First Out) data structure, meaning that tasks are dequeued in the order they arrived.

  1. Microtask Queue

Next to the callback queue, there's another queue called the Microtask Queue. This queue is used for "promise" tasks. Promises in JavaScript are objects that represent the eventual completion or failure of an asynchronous operation.

The difference between the Callback Queue and the Microtask Queue is that tasks in the Microtask Queue have higher priority. After each callback is processed, the Event Loop checks if there’s a function in the Microtask Queue. If there is, it runs that function before moving on to the next callback.

  1. Async/Await & Promises

Promises and async/await are modern ways of dealing with asynchronous operations in JavaScript.

A Promise is an object that may produce a single value sometime in the future. It can be in one of three states: fulfilled, rejected, or pending. Promises are added to the Microtask Queue once they're resolved or rejected.

Async/await is a syntactic sugar built on top of Promises. It makes asynchronous code look and behave like synchronous code. The keyword "async" is used to declare an asynchronous function, while "await" is used to pause async function execution until a Promise is fulfilled or rejected.

In conclusion, the JavaScript Event Loop is a complex but efficient system for handling synchronous and asynchronous operations. By understanding the Call Stack, Web APIs, the Callback Queue, the Microtask Queue, and async/await & Promises, you can better understand and use JavaScript's concurrency model.

Top comments (0)