In this post we will learn how we can simplify callback or promise based NodeJS application with async/await. If you want to read about promise in NodeJS then please read my previous post here.

Async function is natively available in NodeJS and declared with async keyword. Async always return a promise, even if you don’t explicitly write them to do so. Also, the await keyword is only available inside async functions at the moment — it cannot be used in the global scope.

What is the benefits of async/await

  1. It allow us to use await keyword inside async function. Without async keyword await it treated as error
  2. It allow async functions to return promise

Example of Promise/async/await/Normal JS function. All below three functions a, b, c are identical

/**
* @returns {Promise<string>}
*/

function a() {
return Promise.resolve('a');
}
async function b() {
return Promise.resolve('b');
}

async function c() {
return 'c';
}
console.log(a());
console.log(b());
console.log(c());

In promise we have to write .then with callback function but in async await we can simply get rid of .then functions (.then is replaced by await).

let run = async () => {
// Promise version of code
read('../dir/file1.txt')
.then(data => {
console.log(data.toString());
}).catch(err => {
console.log(err)
})

// Async/Await version
const data = await read('../dir/file1.txt');
console.log(data.toString());

// Async-Await version of reading multiple files
const [data1, data2, data3] = await Promise.all([
read('../dir/file1.txt'),
read('../dir/file2.txt'),
read('../dir/file3.txt')
])

console.log(data1.toString());
console.log(data2.toString());
console.log(data3.toString());
}

run()

When we use async/await, we rarely need .then, because await handles the waiting for us.

If a promise resolves normally, then await promise returns the result. But in the case of a rejection, it throws the error, just as if there were a throw statement at that line. Below code snippet and

async function getData() {
return Promise.reject(new Error("New Error!"));
}

this code snippet are identical

async function getData() {
return new Error("New Error!");
}

We can catch that error using try..catch, the same way as a regular throw. In the case of an error, the control jumps to the catch block.

async function getData() {

try {
let response = await fetch('http://someurl');
} catch (err) {
// Error!
alert(err);
}
}

getData();

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

async function getData() {
let response = await fetch('http://someurl');
}

// getData() becomes a rejected promise
getData().catch(alert); // Error!

If we forget to add .catch there, then we get an unhandled promise error (viewable in the console). We can catch such errors using a global unhandledrejection event handler.

That’s all i have to share on async/await. If you have more points to share please comment down below. It will help me and others to gain more knowledge on async/await. Thanks for reading. Please follow to support and more contents like this.

Did you enjoy this article? If so, get more similar content by subscribing to Decoded, our YouTube channel!

Note: More exciting contents are also available on https://ajaykrp.me. Please check it out.