Async Await in JavaScript
Learn via video courses
Overview
Working with asynchronous code can be a bit confusing for both new as well as experienced javascript developers. Over the years, javascript has introduced simpler ways to handle asynchronous operations. Initially, callbacks were used to handle asynchronous operations, and later Promises were introduced in ES2015. But still, the implementation of Promises has syntax complexity which makes it difficult to understand and implement in the code. So to simplify the syntax for asynchronous code, async-await was introduced in ECMA2016. Async awaits javascript is based on the concept of promises with simple code syntax.
Prerequisites
- Recommended to have a good knowledge of Promises as Async and await in javascript are based on the concept of promises
Why were async/await Introduced?
To understand the introduction of async/await in javascript, you need to first understand the evolution of asynchronous functions in javascript. Initially, callback functions were used to make the program asynchronous by passing the asynchronous tasks as arguments to callbacks. But the callbacks had some major drawbacks like callback hells (an issue caused due to complex nested callbacks in the program making it difficult to debug and maintain).
Then the concept of Promises was introduced in ES6 to handle the asynchronous code. Promises are objects in javascript that guarantee to return a value in the future. By using promises, the asynchronous code could be written in a synchronous way by the chaining of promises by multiple then() methods. But Promises can still be confusing and difficult to implement for developers because of its complex code syntax. So to provide a more synchronous way to write asynchronous tasks, ECMAScript 2016 (ES7) introduced async and the await keyword to make working with the promises super easy as async/await makes asynchronous code in traditional synchronous javascript syntax.
The async Keyword
The Async keyword is added before a function to represent that the function is an asynchronous function. The async function simplifies the asynchronous code in a synchronous syntax. The async function always returns a Promise.
Syntax of async function:
The await Keyword
The await keyword is used inside the async function to wait for the asynchronous task to complete its execution. The await keyword pauses the execution of async function until the promise returns a value.
Syntax of await keyword:
Rewriting Promise Code with async/await
Now Let's see how we can make use of async/await in our program in place of simply using promises in your code:
Let's first see simple code with promises:
Output:
Now Let's rewrite the code using async/await in the code:
Ouptut:
How does Async/Await Work?
Async/Await was introduced to solve the issues faced in Promises and provide a simpler way to read and write asynchronous code. Under the hood, Async/Await also uses Promises to write the asynchronous code.
To use async and await in the code, an async function needs to be specified. The async function returns a promise that can be resolved in the later part of the code. And if any task is required to be executed after the completion of any function, we use await keyword. Await keyword pauses the async function for a bit until the requested function returns something. Thus, using await keyword frees the resources to perform other actions meanwhile the awaited function is getting executed.
Example:
Explanation: In the above code, exampleFunc() is an async function. So while the execution of exampleFunc() is taking place the javascript will run the other tasks after it is out of order.
And await inside the async function pauses the execution of the async function until any result value is returned.
How to add error handling
You can handle errors in async functions by adding catch() method to the async function to catch the errors.
Syntax of error handling with catch() method:
The other way of handling errors while using async await in javascript is by using using the typical try-catch block method to handle errors.
Example:
Output:
Awaiting a Promise.all() call
It's suggested in javascript, to use await Promise.all() instead of using await multiple times in a row. Let's understand the reason behind it. One of the main reasons is the fail-fast behavior of Promise.all(), this behavior is useful in the scenario where multiple concurrent operations are executing then why wait for operations with longer execution time to complete when an operation with shorter execution has already thrown some error?
How to Handle async/await Slowdown
While building your application, it's very important to check that the async and await cases are not slowing down your application. The slowdown might happen due to multiple promises with await keywords in a row. So you must keep the following points in mind while using async/await in your program so that it does not slow down your application:
- You should not use await inside loops and you should also avoid using await multiple times in a row. Instead, you can create an array of Promises and call await Promise.all().
- If you are using async functions with await then make sure that unrelated async calls do not block each other.
Async/await Class Methods
To make any method of a class asynchronous you need to add async keyword before the method.
Example:
Similar to the await implementaion elsewhere, await keyword can be used inside the async methods to wait for some tasks to complete.
Note: You can not use async with constructor of the class as the async method should return a promise whereas, constructor returns the object it is constructing.
Await Accepts "thenables"
Let's understand thenables first, thenables are not promises but similar to promises they can added to the right side of await (i.e., await accepts thenables). Thenables are basically objects with callabale then() method. The idea behind using thenable is that a 3rd-party object may not be a promise, but may be promise-compatible. So if that 3-party object supports .then() method, then we can use that 3-party object with await.
Example:
Output:
Explanation: In the above code, await gets a non-promise object with then() method. The then() method has two functions as arguments i.e., resolve and reject. Await in such cases waits until any of the functions resolve or reject is called in the then() method.
Benefits of Using async Function
The benefits of using async / await over promises and the callback function in javascript are listed below:
- Async/await makes asynchronous code in traditional synchronous javascript syntax. This improves the code's readability and makes the code easy to write and maintain.
- Due to the simplified syntax of asynchronous code by async and await, code debugging becomes very easy.
- Error can be handled very easily in async/await code using the try-catch handlers.
Conclusion
- Async/await is based on the concept of Promises. It simplifies the complex syntax for writing asynchronous code.
- Async/await makes the asynchronous code easy to read and write.
- To make a function asynchronous, you need to add an async keyword before it.
- The async function must always return a promise.
- Await keyword is used inside async functions. Await pauses the execution of the async function until a result is returned from the promise.
- Error handling in async/await can be done by the try-catch method.