UI Development

Understanding async Javascript

Introduction

JavaScript is a single-threaded programming language which means only one thing can happen at a time. This means we can’t perform long operations such as network access without blocking the main thread. Suppose we want to request some data from an API and show the results based on data we receive as response from the API. In this scenario server might take some time to process the request and code written for displaying that result will encounter error as the response yet is unavailable.

To avoid such things, we need asynchronous JavaScript. Using asynchronous JavaScript (such as callbacks, promises, and async/await), we can perform long network requests without blocking the main thread.

Let us dive deeper into callbacks, promises and async/await :-

A Brief Overview about Callbacks and problems associated with using nested Callbacks

We all know, a callback is a function that is to be executed after another function has finished executing. Callbacks are good for simple cases.

But once the project requirements start to swell, we will see the piling layers of nested callbacks, which is also known as Callback Hell. So it is recommended to avoid deeply-nested callbacks. To solve this problem, the concept of Promises has been introduced in ES6.

Promises

Promises were the next logical step in escaping callback hell. This method did not remove the use of callbacks, but it made the chaining of functions straightforward and simplified the code, making it much easier to read.

A promise has to be in one of the three states mentioned below:-

  • pending: the promise’s outcome hasn’t yet been determined because the asynchronous operation that will produce its result hasn’t completed yet.
  • fulfilled: the asynchronous operation has completed, and the promise has a value.
  • rejected: the asynchronous operation failed, and the promise will never be fulfilled. In the rejected state, a promise has a reason that indicates why the operation failed.

When a promise is pending, it can transition to the fulfilled or rejected state. Once a promise is fulfilled or rejected, however, it will never transition to any other state, and its value or failure reason will not change.

While using Promise approach we can

  • Flatten callbacks
  • Return values from asynchronous function
  • Throw and Catch exceptions

In the above example of Promise approach func1() should return a Promise Object. This Promise object has two methods, “then” and “catch”. These methods will later be called depending on the state (fulfilled || rejected) of the Promise Object.

Promises gave us an easier way to deal with asynchrony in our code in sequential manner with the concept of async/await functions which has been introduced in ES8. Let us look into async/await functions with more clarity.

Async/Await

Async/await functions help us even more in allowing us to write completely synchronous looking code while performing asynchronous tasks behind the scenes.

async:-

The word “async” before a function means one simple thing: a function always returns a promise and if it is not returned then JavaScript automatically wraps it in a promise which is resolved with its value.

Let’s use the async keyword. It can be placed before a function, like this:

We could explicitly return a promise, which would be the same:

So, async ensures that the function returns a promise, and wraps non-promises in it. There is another keyword, await.

await:- 

await works only inside async functions. await makes JavaScript wait until that promise settles and returns its result.

Here’s an example with a promise that resolves in 2 seconds:

await and parallelism:- 

When we need to wait for multiple promises, we can wrap them in Promise.all and then await:

Error Handling:- 

The promise may take some time before it rejects. In that case there will be a delay before await throws an error. We can catch that error using try and catch, the same way as a regular throw:-

If we don’t have try and catch, then the promise generated by the call of the async function f() becomes rejected. We can append .catch to handle it:

Browser Compatibility:- 

 

About The Author