Callback and Microtask Queues Explained
Tags: javascript, programming, webdev, beginners
Published: 2023-01-03 06:16:55



Javascript is a _**non-blocking**_ single threaded programming language, which means that all functions we write in a `.js` file are executed into the JS engine in one thread at runtime. 

## But, what does non-blocking mean?
Whenever a javascript program needs to execute an async process provided by a _**browser web api**_, this can use a strategy to avoid blocking the main thread, thus getting async responses from web apis further on. Have a look at the following analogy with a calling to a help desk ([you may want to read this too](https://dev.to/mcwiise/brief-intro-to-reactive-streams-with-project-reactor-412o)):

![no blocking](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o0v2qvfrigjnb5phagu1.jpg)

In general terms, the goal is to receive responses from async processes by using **_callback functions_**, meanwhile the program continues its execution in the main thread (going to cinema :P )

## What are Web API's?
Web API's are a bunch of _**built in functions**_ which come with the browser and enable web sites written with javascript to access common functionalities such as:

- _Timeout API:_ To delay the execution of a function.
- _DOM API:_ To manipulate parts of the DOM at runtime.
- _Fetch API:_ To send http requests to servers.
- _LocalStorage API:_ To save information in the browser.
- _Console API:_: To print out to the web console.
- _Location API:_ To get access to geo location services.

In other words, web apis are whatever we can do with the global scope `window`:

```javascript
window.setTimeout(() => {console.log('text')}, 3600);
window.console.log(window.document.title);
window.fetch('www.google.com')
.then(r => {
  console.log(r);
})
window.localStorage.setItem('tales', 'tales');
console.log(window.location.href);
```
## The Callback Queue 
Whenever we use a web API from our javascript code, the program needs to register a _**callback function**_ which will be executed once the web API ends with its internal stuff. 

Now, callback functions don't get the call stack directly, so web API's push them to an alternative channel known as _**the callback queue**_ waiting for the call stack to be ready to stack them for the program to execute them. Have a look at the following snippet:
```javascript
window.setTimeout(() => {console.log('end')}, 1000)
```
In the images below we can see that as soon as the `setTimeout()` function gets into the call stack its callback is registered, and when the timeout has elapsed (1 second) the callback function gets into the callback queue.

![callback queue](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xxj0p57cannf3w120fws.jpg)

## The Event Loop
The event loop is an endless built in process provided by the browser which checks the callback queue looking for functions to execute once the call stack is ready.

And _**When is the call stack ready?**_ it is ready when the Global Execution Context has been removed, then the event loop takes the next function from the callback queue and pushes it to the call stack. 

![event loop](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1d27m06a16m1921kiezi.jpg)

## The Microtask Queue
There are some web API's which use _**promises**_ to provide async computation, this is the case of **_fetch web API._** Have a look at the following snippet:
```javascript
window.fetch('www.google.com')
.then(r => {
  console.log(r);
})
```
Callback functions of web API's based on promises don't get the callback queue after the promise is resolved but a different one called _**The Microtask Queue**_. Even though this queue is also checked by the event loop looking for functions to push to the call stack, this has a higher priority than the callback queue, it means that all callback functions in the **_Microtask Queue_** will be executed first than the next function available in the **_Callback Queue._**