Asynchronous Javascript

6 min read

Asynchronous Javascript

🎉 Brief Overview of what you will learn in this article:

  • What is asynchronicity in Javascript?
  • How javascript code is executed under the hood?
  • Introduction to Web APIs like setTimeout and how they work
  • Basics of Event Loop, Call Stack, and Callback Queue.

The word asynchronous generally refers to two or more events not happening at the same time. It means a task-A can be done while waiting for another task-B to be done. Let's me show you what that means by an example:

🍔 A Scenario to understand asynchronous tasks:

Suppose you go out to a burger king restaurant and ordered a cheeseburger but the restaurant was quite busy that day therefore the staff noted your order and told you that it will take some time to process your order and will notify you when it's done. Now you see a soft drink machine and purchased a coke while your burger order was still processing. This is a simple example of an asynchronous event in which while you were waiting for your order to process, you continued with another task of buying coke, instead of scheduling the task of buying coke after you got your burger.

Asynchronicity in Javascript

Consider the code below:

console.log("start");

const data = getDataAndWait(); // it could take any amount of time
console.log(data);

console.log("end");

Imagine if there is a function getDataAndWait() which gets the data from a remote source and returns it. Here, the code after line 3 would not run until the getDataAndWait function returns something and therefore it prevents the execution of further code. This is because javascript is actually a synchronous language.

🤷‍♂️ Synchronous... Wha???

Javascript is synchronous (each line is executed in order the code appears) and single-threaded Language (one command executing at a time). Although it's synchronous in nature, we would still want to perform some tasks asynchronously like waiting for data to come from an API server or perhaps waiting for a timer to finish but we also do not want to block the rest of the code from executing while we are waiting. This is why we need to figure out a way to use asynchronicity in a language that is synchronous.

✅ Defining what our end goals are

  • We would like to be able to do a task that takes some time to complete, like fetching data from an API
  • We would want to simultaneously execute the rest of the code line by line while waiting for a response from a long time taking task
  • When that time-consuming task completes, we would want to be able to know that the task and its functionality are done.

Earlier I said that we need a way to use asynchronicity in javascript. But javascript is synchronous, right. So how can we do that? The answer is we don't need to because that is where Web APIs come into play.

🌈 Web APIs & amazing features of a browser

The browser you are using right now is actually quite powerful in the way that it can perform various tasks that javascript cannot. It has amazing tools like a timer, local storage, indexedDB, getting a client's geolocation, interacting with the DOM elements, fetching data from the internet, and so on. For example, the function setTimeout is actually a web API and not part of the javascript language itself. The console is another example of web API, 😲 surprising isn't it? The web browser exposes the web API like console which can be accessed from any global object.

A Solution:

console.log("start");

setTimeout(function cb(){
  console.log("Hello")
}, 1000);

console.log("end");

Let's dive a little deep into the execution of the code line by line.

Brief summary of how code is executed under the hood

Everything in Javascript happens inside the Execution Context. Whenever a program is run, a global execution context is created inside the Call Stack and when the program is done executing, the global execution context is popped off the call stack.

  • When line 1 is executed since you know that console and setTimeout are not part of javascript but actually features of Browser. The console.log() will use the console API of the browser and log the string start into the console window.
Logging Start to Console
  • Now on line 3, setTimeout() will use the timer feature and activate the time for 1000 milliseconds and register the cb() function.
setTimeout registering function cb
  • Now control moves over the next line of code and logs end to the console window. Since there is no code left, the program is executed and the global execution context is popped off the Call Stack. The synchronous Javascript code is done now. But wait, what about the function cb because after that 1000 ms timer expires, the cb function needs to be executed, but that doesn't happen directly.
Logging end to console and end of synchronous code

Event Loop & Callback Queue

As soon as the timer expires, the function cb is moved inside the Callback Queue which is a queue having code that is waiting to be pushed inside the Call Stack. But when is this function allowed to go in? Something that continuously loops and checks if the call stack is empty or not. If there's some code waiting to be executed in the Callback Queue, it quickly pushes it into the Call Stack and then the code is executed. That something is known as Event Loop

Passing cb into the callback queue
  • Hence, the cb is executed and it logs the word hello on the browser console.
Event Loop pushes cb into call stack and cb gets executed
//This is the output of the code
start
end
hello

Look like we have got what we wanted. The cb function is executed after some time without blocking the execution of the rest of the code. But there are some drawbacks with this approach:

  • The main task of cb was to log hello into the browser console window, but that is available in the callback function. This doesn't sound much of a problem because the example was very short. But in a real-world application, the asynchronous code often ends up with a callback inside another callback and so on. This is known as Callback Hell.
  • Passing a function into another function might feel a bit odd just to execute it after some time.

👋 That all for this article, I don't want to bore you people so, in the next article, we will look at another solution to write asynchronous code through promises. If there's something you would like to talk about you can ask me in the comments or, you can directly reach out to me on Twitter @AyushCodes

📖 Resources

⚡ Originally published at dev.to/ayushcodes

If you found this article helpful, I would be grateful for your support.
"Buy me some paneer curry"

Comments

I'd love to read your thoughts on this article!!!