A Sneak Peek At Asynchronous JavaScript
Tags: asynchronous, async, promise, javascript
Published: 2020-02-24 10:52:31

---
title: A Sneak Peek At Asynchronous JavaScript
published: true
cover_image: https://images.unsplash.com/photo-1546957236-5fde4e0b25eb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=751&q=80
date: 2020-01-31 06:47:31 UTC
tags: asynchronous,async,promise,javascript
canonical_url: 
---


The word "Asynchronous" means  something will happen in the future without blocking other tasks.

Let's say we wrote some instructions with JavaScript.

```
A. do this
B. do this
C. do this
```

A will be executed
then B
then C

Serially, common sense, right ?
But sometimes, it’s not the case. Let’s see -

```javascript
let name = "Heisenberg"
```

This variable `name` has a `value`. You want to print out this value.

```javascript
console.log(name)
```

What if this `value` isn’t available in your code. It’s somewhere else outside . Maybe some server serves this `value` when we send HTTP request. Or maybe it’s inside a file.

So it’s not in your code right now. Your program will have to fetch it from outside.

Now the code looks like this -

```javascript
let name;

// some imaginary Service
// which sends us a String value as response
fetch("/saymyname")
  .then( res => res.text() )
  .then( value => name = value )

console.log(name)
```

There’s a bug in the code.  
The output would be - `undefined`.

`name` variable is still `undefined`. It wasn’t overridden as we wanted to do inside the fetch code.

That’s because JavaScript skips this fetching operation and continues executing the following lines of your code.

This fetching happens in the background by the Operating System and we get a `Promise` in our code that, when the resolved `value` will be available, we can use that data. And that’s why we’ll have to move our printing operation there too.

```javascript
let name

fetch("/saymyname")
  .then( res => res.text() )
  .then( value => {
     name = value
     console.log(name)
   })
```

We've just used some **Async** code.

Normally JavaScript is Synchronous. But there are some specific APIs in the language which are Asynchronous by nature. Like here we’ve used fetch API.

It’s a good thing because otherwise this program would freeze until the data is available for us.

But this is also problematic because it’s not a regular way of writing code, there’s an overhead of keeping async things in the sync. For this, we have a much cleaner API now  —  Async/Await. Which also blocks, but you get to control where and when you want to block.

Another thing we want to take advantage of is  —  Parallel Execution (Concurrent precisely). In our previous example,  if we had multiple fetching operations, they would happen in parallel. Thanks to the multi threading interface of Operating System.

To understand this let’s look at another example. Say we want to read text from 2 different files.

```javascript
async function readFiles() {
  let text1 = await readFile('/fileOne.txt') // 3 seconds
  console.log("text from file one", text)

  let text2 = await readFile('/fileTwo.text') // 2 seconds
  console.log("text from file two", text)
}

readFiles()

console.log("Processing...")
```

This looks nice, but this is blocking code. They are independent operations. So they should take only 3 seconds to process. But now they are taking 3 + 2 = 5 seconds.

So how to write this in parallel ?

**Promise.all()** - this API handles multiple independent Async operations in paralllel. And we can `await` for the whole process to finish.

```javascript

const [text1, text2] = await Promise.all([
                          readFile('/fileOne.txt'),
                          readFile('/fileTwo.txt')
                        ]) // total 3 seconds

console.log("Done")
```

Here, both file reading operations are parallel and also we get resolved values in sequence. This is great.

Except, this API short circuits. If any of these operations fails, the whole thing fails from that point. What if we want it to work as **Microservice** , meaning  -  an Async operation can fail, but we still want other operations’ resolved values, then we can’t use Promise.all(). Instead we need to use [**Promise.allSettled()**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled).

So now, we have this basic idea that there can be different requirements for Async operations and for handling them there are different variances of Promise API too. For example another useful one is **Promise.race()**.


**Event Loop**

A promise can have 2 states. **Pending** and **Resolved** /Rejected.

A pending promise means  —  it’s currently being handled in the background.
A resolved promise means  —  it will be executed at the end of the running event loop.

On each iteration of event loop, we can consider 3 cases -

1. If it’s a synchronous code, execute it.
2. If it’s a pending Promise then skip it. It’s running in the background.
3. If it’s a resolved(rejected) Promise, then the callback will run at the end of this particular iteration of event loop.

When the resolved Promise is available, it’s then-able. Meaning   we can attach a callback to work with the resolved data. **So a resolved Promise can be available anytime inside a particular iteration of**  **Event Loop**. And the callback will be fired within this same iteration, but at the very end after finishing all the Synchronous works.

Let’s look at an interesting case -

```javascript
setTimeout(()=> console.log('timeout'), 0)

Promise.resolve().then(()=> console.log('resolved promise'))

console.log('synchronous')
```

We are emulating a resolved Promise here and also a timer. So on a running event loop phase, after finishing all the Sync code, it’s going to check

- If there’s any callback of resolved Promise to run.
- If there’s a timer callback to run.

So before the timer callback, it’s going to check if there’s any resolved promise. First they are going to be executed. It doesn’t matter how much time it takes, and in the mean time, there could be other resolved promises popped up in the current event loop. After finishing all of them, the timer callback gets executed finally.

That means, you can’t expect the timer to run after the exact interval you provided, like here we did- 0 ms. It might take longer than that.

So output of the code —

```
synchronous
resolved promise
timeout
```

**N.B**. Different browsers can have different implementations. This is Chrome/Node standard behavior.

To understand how event loop actually works- read this- [https://nodejs.org/uk/docs/guides/event-loop-timers-and-nexttick/](https://nodejs.org/uk/docs/guides/event-loop-timers-and-nexttick/)

And a fantastic article by Jake Archibald on Task, Microtask scheduing -  
[https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/](https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/)

That’s all folks. Have fun with your Asynchronous journey.