Event Loop and Callback Queue in JavaScript

The event loop is the secret behind JavaScript's asynchronous programming. Before we start the event loop discussion, I want you to look into some high-level topics of call stack. JavaScript call stack is a mechanism to keep track of multiple function calls or we can say call stack is to manage multiple execution contexts.

In this article we are going to discuss:

  1. Web APIs
  2. Callback Queue
  3. Microtask Queue
  4. Event loops
  5. How starvation happens

Please have a look at the below diagram to get a better idea of the topics we are discussing.

event loop

Web APIs

Web APIs or Browser APIs are built into your web browser and are able to expose data from the browser and surrounding computer environment and do useful complex things with it. setTimeout(), DOM APIs, fetch(), local storage, location, and console are some examples for Web APIs. They are not part of the JavaScript language, but they are built on top of the core JavaScript language, providing you with extra superpowers to use in your JavaScript code. 

In these web APIs, the browser is actually using some complex lower-level code (e.g. C++ or Rust). But, this complexity is abstracted away from you by the API.

Callback Queue(Macrotask Queue)

Callback Queue or Macrotask Queue is where the callback function gets pushed to, and waits for the execution. Let us dive deep into the callback queue with an example.

setTimeout(abc, 5000);

function abc(){
    console.log("datainfinites");
}

Here, we have a callback function abc(), that is to be executed after 5 seconds of time. After 5 seconds, the callback function abc() does not get directly pushed into the call stack for execution instead it will be pushed into the callback queue. The call stack may be busy with the execution of some other functions. The callback queue keeps all callback functions in a queue that are ready for execution and waits until the call stack gets free. When the call stack is free, the event loop pops the callback function from callback queue and pushes it to the call stack. 

The callback queue was working under the First In First Out(FIFO) principle.

Microtask Queue

Microtask Queue is similar to the Callback Queue(macrotask queue), but microtask queue has a higher priority than the callback queue. All the callback functions coming through promises and mutation observer will go inside the microtask queue. 

For example, in the case of fetch(), it returns a promise and, this callback function will get pushed into the microtask queue. Promise handling always has a higher priority than setTimeout or setInterval. So the event loop gives higher priority to the microtask queue and then looks into callback queue.

Event loops

The event loop keeps running continuously and monitoring the call stack and callback queue. When the call stack gets empty and the event loop sees some callback functions waiting in the microtask queue or callback queue(macrotask queue) for execution. Then, the event loop pops the callback functions one by one from the microtask queue and callback queue and gets pushed into the call stack for execution. The event loop acts like a gatekeeper for the callback queue. 

The microtask queue has higher priority than the callback queue(macrotask queue).

How starvation happens

Let us take a scenario of a callback function from the microtask queue create another callback function, and get pushed into the microtask queue. If this process goes in a loop, then the functions in the callback queue(macrotask queue) will not get any opportunity to execute. This is called starvation in the callback queue.

Related Blogs

pm2 cluster

Scaling Node.js Applications With PM2 Clusters

Learn cluster modules in node js, install and configure PM2 in production, and implement PM2 clusters using the PM2 ecosystem without any modification in the current application code.

call-stack-in-javascript

What is Call Stack in JavaScript

JavaScript Call Stack is a mechanism to keep track of multiple function calls and manage execution context. This article describes how the call stack works with examples.

Factory Design Pattern in JavaScript

Factory Design Pattern in JavaScript

Factory allows you to handle all the object creation in a centralized location which helps the code clean, concise, and maintainable. Understand deeply with examples.

Cannot read property of undefined in JavaScript

Cannot read property of undefined in JavaScript

The TypeError: Cannot read property of undefined occurs when we try to read a property on an undefined variable or when we try to access a property on a DOM element that doesn't exist.

Can't set headers after they are sent to the client

Can't set headers after they are sent to the client

Error “Can't set headers after they are sent to the client” occurs when an express.js application tries to send multiple responses for a single request.

Greatest Common Divisor (GCD) in JavaScript

Find greatest common divisor (GCD) in JavaScript

Find the Greatest Common Divisor(GCD) of two numbers using the Euclidean algorithm in javascript. Calculate GCD for a given integer array.

How to Fix error:0308010C:digital envelope routines::unsupported

How to Fix error:0308010C:digital envelope routines::unsupported

To fix the error:0308010C:digital envelope routines::unsupported, enable the legacy provider for Node.js by passing --openssl-legacy-provider flag to webpack.

Javascript

What are Parameters, Arguments and Arguments Object in JavaScript

In JavaScript, the terms parameters, arguments, and arguments object are related to functions. Explains what they are with examples.

ckeditor

How to Integrate Custom Build CKEditor5 with React

Explains how to create a custom build CKEditor5 and integrate with react with sample code.