DEV Community

Captain Mcwiise
Captain Mcwiise

Posted on

Callback and Microtask Queues Explained

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):

no blocking

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:

window.setTimeout(() => {console.log('text')}, 3600);
.then(r => {
window.localStorage.setItem('tales', 'tales');
Enter fullscreen mode Exit fullscreen mode

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:

window.setTimeout(() => {console.log('end')}, 1000)
Enter fullscreen mode Exit fullscreen mode

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

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

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:

.then(r => {
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)