Asynchronous Javascript
Tags: javascript, web, api, asynchronous
Published: 2021-05-17 08:58:39

🎉 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:
```js
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:
```js
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.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgxralrfkjuzptdmo20a.png)

- Now on line 3, `setTimeout()` will use the timer feature and activate the time for 1000 milliseconds and register the `cb()` function.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2d7q35oxp5o4mp8lnc3a.png)

- 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.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ol88kg5e650dkpv78lec.png)

### 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**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b4xxxlvbhms07l3egn8k.png)

- Hence, the `cb` is executed and it logs the word `hello` on the browser console.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bm6q0eucpq175s8pz5zv.png)
```js
//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](https://twitter.com/AyushCodes)

## 📖 Resources

- [MDN Asynchronous Javascript](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous)
- [Javascript: The New Hard Parts](https://frontendmasters.com/courses/javascript-new-hard-parts)
- [Namaste Javascript: Episode No. 15](https://www.youtube.com/watch?v=8zKuNo4ay8E&list=PLlasXeu85E9cQ32gLCvAvr9vNaUccPVNP&index=17)