The Asynchronous World of JavaScript

The Asynchronous World of JavaScript

Learn how asynchronous programming works in JavaScript language

ยท

4 min read

Introduction

The term "asynchronous" is a combination of the greek term "async" meaning "not with" and "Chronos" meaning "time" is an adjective describing objects or events that are not coordinated with time.

In the programming world, asynchronous programming is a technique that enables your program to start a long task and remain interactive and be able to respond to other events while that task runs, rather than having to wait until the task has finished.

Asynchronous JavaScript

JavaScript is a single-threaded and synchronously executed (each line is run in order as it appears in code) language.

Let's consider a scenario if we are talking to a server and the data takes a long time to reach the client. So, in a synchronous environment, we have to wait until the data comes back to do anything else.

// In synchronous environment
// function to fetch data from twitter
function getTweet(id){
    // data is coming back after 350 ms
}
const tweet = getTweet('1');

// this is going to be exectued after 350 ms
console.log(tweet);    // { data: "My blogs are awesome!" }

In the above example, we can see data takes 350 ms to come back to the client making the code execution blocked for this period.

What if we delay our code?

Let's talk about an asynchronous function provided by JavaScript setTimeout(). According to MDN, setTimeout() method sets a timer that executes a function or specified piece of code once the timer expires.

function printHello(){
    console.log("Hello!");
}
setTimeout(printHello, 1000);    // timer set for 1 second
console.log("Me, first");

/*
    Output:

    Me, first
    Hello!
*/

In the above code, we used setTimeout() method to execute printHello() function after 1 second. But, let's modify our above example,

function printHello(){
    console.log("Hello!");
}
setTimeout(printHello, 0);    // timer set for 0 second
console.log("Me, first");

/*
    Output:

    Me, first
    Hello!
*/

We set a timer for 0 seconds, so printHello() function should be executed instantly but it doesn't happen and the output remains the same. We will see why this is happening in a moment, but first, we need to understand what features the browser provides to us.

Asynchronous Browser Features

The web browser provides us with,

All these features are provided by our web browser and we cannot directly in them, they're written in whatever the browser is written in. These features can only be accessed using some functions (facade functions) present in JavaScript. For example, we are using the timer feature by setTimeout() function.

function printHello(){
    console.log("Hello");
}
setTimeout(printHello, 1000);    // set timer for 1 second
console.log("Me, first");

// Output:
// Me, first
// Hello

Let's see what we are doing in the above code,

Line 1: We are declaring a function named printHello.

Line 2: We are using setTimeout() function to set a timer for 1 second for printHello() function.

Line 3: We are logging "Me, First" in the web console.

In the above image, we can see the flow of execution of our example. But, there is still one problem what if we got more than 1 statement after setTimeout(). So, when will our function result get inserted back?

Callback Queue & Event Loop

Callback Queue is a queue of tasks that are executed after the current task. The JavaScript engine after it has executed all other tasks. When the timer gets expired in our setTimeout() function, it adds the task to the callback queue from where the event loop gets it out after all other code gets executed.

According to MDN, JavaScript has a runtime model based on an event loop, which is responsible for executing the code, collecting and processing events, and executing queued sub-tasks.

Let's see an example,

function printHello(){
    console.log("Hello!");
}

setTimeout(printHello, 0);    // sets timer for 0 ms
console.log("Me, first");
console.log("Me, second");

/*
    Output:

    Me, first
    Me, second
    Hello!
*/

The printHello() function gets executed after all the console.log() statements get executed because the task gets added to the callback queue by setTimeout() and the event loop takes it out after everything else gets executed.

In the above diagram, we can see how the event loop (green arrows) controls the flow of execution.

Rule by which function is allowed to be out of the callback queue,

  • When all the synchronous code is executed.

  • If we have a 1 million console.log() statements they all get executed first, then our event loop takes the function out from the callback queue and pushes it on the call stack.

Advantages of Asynchronous programming

  • It enhances speed, responsiveness, and user experience.

  • The response time of one task does not affect another task.

  • You can use more than one feature, even if other features are running.

Conclusion

In this blog, we discussed asynchronous programming and how it can make our application more efficient. We also talked about features provided by web browsers, callback queue, and event loop.

If you're having any doubts please mention them in the comments below! ๐Ÿ˜Ž

References

ย