Understanding async/await in Node.js
Async
/await
is a native feature available in Node.js that makes it easier to manage tasks that take time, like waiting for a response from an API. In Node.js, where it’s common to handle many tasks simultaneously, async
/await
keeps our asynchronous code organized and more readable.
Async
/await
is a syntactic sugar built on top of promises. In this blog post, you’ll learn how to use async
/await
in your own code and see how it differs from other syntaxes.
What are promises?
A promise is a placeholder value that will eventually be filled in the future. The idea is similar to the familiar concept of real-world promises. For example, if you make a promise to do the dishes, that is an assurance that the dishes will be done eventually, which lets you continue on with other tasks.
Promises allow an asynchronous operation to run and wait for the value—while also running any following code (called “callbacks”) in the meantime. Callbacks were originally invoked by passing them as an argument. Promises introduced a new syntax of using then
/catch
statements to chain callbacks together.
This new way of invoking callbacks eliminates the issue that is popularly known as “callback hell” or “promise pyramids,” which occurs when there are multiple chains of callbacks:
firstFunction(args, function() { secondFunction(args, function() { thirdFunction(args, function() { // it can keep going }); }); });
Using then
statements to chain functions together is one way to handle promises better, as it allows for more readable code:
firstFunction(args) .then(secondFunction(args)) .then(thirdFunction(args))
How to declare an async function
We know that async
/await
helps us handle asynchronous operations, but how do we use it?
It’s as easy as declaring a function with the async
keyword. All async
functions return a promise, automatically encapsulating non-promise values. Functions can be made async by using the keyword async
before the function declaration:
async function bakeCookies() { // Simulating baking time await new Promise((resolve) => setTimeout(resolve, 2000)); }
What is await?
Await
is a keyword paired with async
functions that causes the JavaScript interpreter to pause until the following asynchronous operation is run. You can also assign the value to a variable to use later. It’s important to remember that the keyword await can only be placed in the bodies of async functions.
async function serveCookies() { const cookies = await bakeCookies(); console.log("The cookies are now ready to serve!"); } serveCookies()
If we assume that bakeCookies()
in the example above is an asynchronous operation that returns a promise, the await keyword will halt the function serveCookies()
until bakeCookies()
has returned a value.
Why use async/await?
Use async
/await
in Node.js when you want to write asynchronous code that is more readable, sequential, and better at error handling.
This approach reduces the cognitive load for developers, making it easier to understand, read, and debug the code. By maintaining a top-to-bottom flow and utilizing try
/catch
for error handling, async
/await
simplifies the learning curve for those who are new to asynchronous programming.
Error handling with async/await
Without error handling, rejected promises can lead to unhandled promise errors, which can cause your application to behave unpredictably. Async functions can use try
/catch
blocks, which enable you to try a bunch of operations within a block and then catch any errors raised during execution to be handled in the catch
block.
Let’s look at how the experience of fetching data from an API differs when we use then
/catch
and async
/await
. The below snippet shows an example of error handling using then
/catch
:
// Using promises with .then() and .catch() for error handling function fetchData() { return fetch('/endpoint') .then(response => response.text()) .then(summary => { console.log(summary); }) .catch(error => { console.log('Error:' + error.message); }); } // Call fetchData() fetchData();
The following code does the same thing, but it uses async
/await
instead, making the sequential flow easier to parse through:
async function fetchDataAsync() { try { const response = await fetch('/endpoint'); const summary = await response.text(); console.log(summary); } catch (error) { console.log('Error:' + error.message); } } // Call fetchDataAsync() fetchDataAsync();
Try async/await in a project
Now that you’re familiar with how to use async
/await
, start by getting hands-on experience through the Postman Student Program’s newest Project-Based Learning module! Learn how to build a full stack AI text summarizer app with the help of Postman, while handling promises with async
/await
along the way:
Postman Student Programs gives students the opportunity to dive into the fascinating world of APIs, gain valuable insights, and earn a free certificate through comprehensive training. Sign up to gain instant access to our free Postman API Fundamentals Student Expert certification and learning modules in Postman Academy.
Thank you Lillian I come from Java and I’m trying to learn NodeJs but regarding promises and async/await they have been some of the weird topics to me, however you explained the topic clearly, and easy to understand