Asynchronous JavaScript

Betül Erkoç
5 min readJun 10, 2022

Let’s say there is an event you will attend this evening. There will be several steps to complete in order to get ready. Such as:
- wash hair
- blow-dry
- makeup
- manicure
- pedicure
- get dressed

If you are going to do everything by yourself in order, this will be similar to the JavaScript single thread synchronous way of working since code lines in JavaScript are executed in order, one after the other.

the output of the getReady function

Let’s give each task time roughly as follows:

- wash hair - 5 min
- blow-dry - 20 min
- makeup - 15 min
- manicure - 7 min
- pedicure - 8 min
- get dressed - 3 min

Seems it will take a lot of time, right? So, what else you can do? Maybe you can go to the hairdresser to make each work more organized and also reduce the time. Going to the hairdresser is actually very similar to stepping into the asynchronous JavaScript world. What do I mean? Let’s dive into it and make our tasks asynchronous.

Since I do not want to wait for these operations for minutes, I will use seconds instead of minutes in the setTimeout function.

the output of the getAsyncReady function

Okay, seems we achieved making tasks asynchronous but we have another issue now. Check the output and tell me, do you really want to get dressed before washing your hair? Also, if the makeup is completed before blow-drying, heat may affect the makeup. Apart from manicure and pedicure, there are dependent tasks.

Order is important, while in our world your dress may get wet or your makeup may running out, in JavaScript world you need to deal with undefined or null 😓

Moreover, cutting off the water, running out of shampoo, or power cut will also affect the next steps. For example, if the water is cut off, your hair will not be washed and your hair will not be blow-dried, but this will not have any effect on your manicure and pedicure. Briefly, we would like to know what happened or where it stuck. That means we need more control over our process and we can handle it in JavaScript in three ways.

  1. Callback
  2. Promises
  3. Async-await

1.Callback

Since functions are first-class citizens in JavaScript, you can pass a function as an argument to another function. In fact, when we used the setTimeout function, we used callback. With the setTimeout function, we pass as an argument the function that will be executed after the timer expires. Let’s try to make our code more manageable.

the output of getReadyWithCallback function

Yippee! The order is exactly as we wanted ✨

For basic scenarios, callbacks are quite handy. On the other hand, each callback adds another level of nesting as seen in our example, and once you have a lot of callbacks, the code eventually becomes complicated and hard to debug. Let’s take a look at promises as an alternative to callbacks.

2. Promises

Promises are one approach to avoid callback hell when handling asynchronous code. First, we need to create a promise using the Promise constructor. Also, we need to specify by using resolve and reject callback what we desire to happen when a promise returns successfully or throws an error. This promise will result in either a value that can be a resolved value or a reason for rejection. We will use .then() function to handle the result of the promise, as well as .catch() method to manage any errors.

Let’s say there is no electricity, remove electricity from the code and see what will happen.

the output of getReadyWithPromise function when there is no electricity

In our example, a promise is returned to another promise which is known as a promise chain. When there are several operations, we should add additional then() blocks to the end of each one. Even if our code is no longer nested, it still seems to be difficult to read and debug. Promises were created to resolve the callback hell problem, but they bring syntactic complexity, so understood that promises cannot be the final solution. Let’s have a look at another callback alternative, async-await.

3. async-await

Async-await is simply syntactic sugar for promises since it still uses promises under the hood. The promise is returned by an async function. By prepending await keyword to the function, the caller code will wait until the promise is resolved or rejected before proceeding.

Let’s try to get ready by using async-await:

the output of getReadyAsyncAwait function

Only async functions are allowed to use the await keyword.

Overall, we achieved being ready at the end of the day by using three different approaches 🎉 🎉 🎉

References

--

--