Asynchronous Programming in JavaScript using promises, async and await

Before we see what is asynchronous code let’s make sure we understand what is synchronous code.

What is synchronous code?

It is the normal JavaScript code we write. Synchronous codes are executed line by line in the exact order of execution. Each line of code waits for the previous line to finish and executes as soon as the browser can execute it. Since JavaScript is single-threaded only one thing can happen at a time and long-running codes can block the execution of the code. Therefore, it can affect the performance of the program. So, in order to solve this JavaScript is asynchronous. It uses an event loop to run the blocking codes without affecting the performance of the code.

The output of the above code is -

So here we can see that it executes in the order code is written.

What is asynchronous code?

This code is executed after a task that runs in the background finishes. Asynchronous code is non-blocking which means execution doesn’t wait for an asynchronous task to complete its job. Instead, this asynchronous task runs in the background using the event loop and is added to the stack for execution after the task has been completed while the code execution continues normally.

Examples for asynchronous codes are –

· Event Listeners

· SetTimeouts

· Fetching data through APIs.

Since JavaScript is implemented in a non-blocking manner, you’ll need to perform some additional steps in order to handle the result before further code is being executed.

Let’s look at an example of asynchronous code and the output we will get if we didn’t handle it.

If we analyze the above code, it is a function that has a setTimeout() that has a delay of 1s and after 1s it will assign the value of num variable to 100 and it returns the value of the num variable. Finally, the function has been called. So what do you think the output would be? We would expect the output to be 100 but the actual output is undefined.

The reason that the function returns undefined is that JavaScript is non-blocking it doesn’t wait until setTimeout gets completed so it returns num before 100 is assigned to num variable, therefore it returns undefined.

So if we need to get 100 as the output what should we do?

We should handle this asynchronous code in order to return the value only after the asynchronous task has been completed.

We can handle it using callbacks and promises. Callbacks can lead to a problem called callback Hell. So, in this blog, I will discuss how to use promises to solve this problem.

Promises

A promise is an object that is used as a placeholder for the future result of an asynchronous operation. Simply a promise is a container for a future value. So now we no longer need to rely on events and callbacks passed into asynchronous functions to handle asynchronous results. Instead of nesting callbacks, we can chain promises for a sequence of asynchronous operations.

Promises simplify the handling and improve the readability of asynchronous code.

How to use promises to handle asynchronous code?

Now let’s see how we can solve the earlier problem using promises in order to get the expected results.

We need to return an object from the Promise class. Promise class constructor requires a function with 2 parameters: resolve and reject. Inside the body of this function, we need to insert the asynchronous code. It is also clear from the above image that setTimeout which is an asynchronous code is written within the body of the function in the constructor of the Promise.

We can return a value from this function using the resolve() method. The return value should be passed as a parameter to the resolve method. This resolve method will return the value as a promise.

The reject() method can be used to handle errors. It will return an error if there are any errors.

So now let’s see whether we can call this function as we call a normal function.

We might expect the output to be 100 but since the resolve() method returns a promise, it outputs a promise.

So now if we need to get the expected value we need to handle these promises.

We can handle promises using 2 methods :

1. Using then keyword

2. Using ‘async’ and ‘await’

The then() method accepts a function with a parameter to capture the returning value from the promise and inside the body of the function, we can output it to the console in order to get the expected value.

So now let’s see whether we will be able to get 100 as the output.

Finally, we are able to get the expected output.

Since we have used normal functions inside then the code looks a bit complicated, we can simplify it by using arrow functions.

The above code written using the arrow function is shown below.

We can also handle the errors returned by the asynchronous code using a catch block.

2. Using Async and Await

These two keywords have been added to JavaScript from the ES2017 version. The handling of promises becomes easier by using async and await.

Normally async and await are used if we need the value returned by an asynchronous code to perform some operations.

Let’s look at an example to get a better understanding.

The implementation of the getValue function has not changed. It returns a promise as we saw earlier. What has changed is the getValue function has been called inside an async function. The async keyword is used to indicate that this function is executing an asynchronous code based on Promise. Async functions will keep running in the background and also will return a promise once completed.

Inside the print function, the getValue function is called by using the await keyword. This keyword implies that getValue is returning a Promise and we have to wait for the Promise to be resolved or rejected. The await keyword will pause the execution until a value is returned from the asynchronous code. The next line of the code is executed only after the promise (returned from getvalue) has been resolved.

The await keyword can be used only within async functions.

If this function was a normal function it would have returned undefined since it doesn’t wait for the execution of the asynchronous code but as this is an async function ‘return value + 100’ statement will only be executed after the getValue function returns a value

Now let’s call the function and see whether we can get the expected output as 200.

The output is

Since async functions also return a promise we should handle them using the then method to get the expected results.

3rd year Software Engineering Undergraduate