JavaScript Concurrency and Event Loop

2022-01-04 . 2 min read

Disclaimer


This blog post will be quite different; Different such that the topic of the post is already discussed and talked about by many people and has many existing amazing resources to understand. This post links some amazing resources relating to the topic.

Let's start


Understanding your programming language from the root can be helpful to avoid bugs, debug, write and be an efficient programmer. We’ve all been hearing that Javascript is a single-threaded language; mostly in the node community. We actually have only one execution thread, but the language has the means to accomplish concurrency which includes using callbacks and promises. Tasks that can take a long time to return like fetching data from a remote server or even local disk I/O tasks when run synchronously block the execution of later tasks and the browser gives us a warning like “A script is busy or stopped responding...”. That is the reason why JS programmers are always motivated to write non-blocking code and also the reason they are very good at asynchronous programming.

Blocking vs Non-Blocking Code


Blocking code that takes a large amount of time to process should be handled asynchronously. It pauses the execution of any other tasks and for example, in the front end, such tasks can make the screen unresponsive which many of us have already experienced. It is always advised to use a non-blocking code. A blocking code on a server can freeze the server from working on additional incoming requests.

This article on nodejs.org talks about blocking and non-blocking code when to use, the dangers of mixing both types using file I/O operation.

Event Loop, Callbacks, Promises


Philip Roberts has an amazing talk with the topic “What the heck is the event loop anyway?” where he uses an amazing resource that he created to visualize the event loop and the processes.

Here is the resource.

JS runtime has an event loop that looks out for tasks queued on the task queue and puts them for execution on the call stack.

console.log("I am first")
setTimeout(() => console.log("Am I second?"), 0)
console.log("An I third?")

The above 3 lined examples can really help what is really happening inside the runtime. Guess the output to try running it and see it for yourself.

This is an amazing page on the MDN site which guides on asynchronous javascript.

This is another resource on The Odin Project for understanding all about asynchronous javascript step by step.

Below is a piece of code from one of my personal projects where a route has a callback which is called when the route is triggered.

Notice that the callback has another callback inside it’s body. Though it might not look like an issue in this code, in certain situations we might run into a situation when we encounter lots of nested callbacks and fall into the callback hell.

postRoutes.post(URL, (err_1, data_1) => {
    if (err_2) ...HANDLE_ERROR...
    else ...DO_YOUR_THING...
    ANOTHER_METHOD({ ... }, (err_2, data_2) => {  
        if (err_2) ...HANDLE_ERROR...
        else ...DO_YOUR_THING...
    })
})

Promises are a great way to write clean asynchronous code. Below is a piece of code that uses JS promises which triggers the route shown above.

fetch(URL, {
            method: "post",
            headers: { ...headers... },
            body: JSON.stringify({ ...body })
 })
.then(res => res.json())
.then((data) => {
            ...DO_YOUR_THING...
        })
.then((data) => {
                ...DO_YOUR_THING...
          })
.catch(() => {
              ...handle Error...
          })

All Resources



Hey I assume you finished reading, I would love to know your feedback or if found any error or mistake in this blog post, please do not hesitate to reach out to me.