How to use async/await in Node.js
© https://nodejs.org/en/

How to use async/await in Node.js

How to use async/await with Promises in Node

By Mario Kandut

Europe’s developer-focused job platform

Let companies apply to you

Developer-focused, salary and tech stack upfront.

Just one profile, no job applications!

This article is based on Node v16.14.0.

Async/Await can be used to write asynchronous code in Node.js that reads like synchronous code and is available in Node since v.7.6 and up (officially rolled out with Node v8 and ECMAScript 2017). Any code that uses Promises can be converted to use async/await. For an overview of promises in Node.js have a look at the article: Promises in Node.js

What is async/await?

💰 The Pragmatic Programmer: journey to mastery. 💰 One of the best books in software development, sold over 200,000 times.

The basic idea behind async/await is to write async code that behaves similarly to synchronous code, it should execute in the order it was written.

Let's look at an example to compare code execution with Promises and with async/await:

Create or add a project folder.

mkdir node-async-await

Initialize project with npm init -y to be able to install node packages.

cd node-async-await
npm init -y

Install node-fetch to make fetch requests.

npm install node-fetch

Create an index.js file.

touch index.js

Copy example code:

const fetch = require('node-fetch');

async function run() {
  const status = await fetch(
    'https://jsonplaceholder.typicode.com/todos/1',
  )
    .then(response => response.json())
    .then(res => res);
  console.log(status, 'Complete!');
}
run();

We need a second file for the comparison code for Promises.

touch index-promise.js

Copy the example code:

const fetch = require('node-fetch');

const data = fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(res => res);
console.log(data, 'Complete!');

Now execute both files.

With async/await code execution inside the run function is paused without blocking the Node.js process until the Promise chain resolves. Without async/await the console.log statement will run before the Promise has resolved. The output in the command line will look like this Promise { <pending> } Complete!.

If we want the same behaviour as the async/await with just Promises the console.log has to be nested to ensure data was present when using it. With async/await we don't have to nest the code, so it is more readable.

Async functions will implicitly return a Promise, which resolves with the return value from the function. Using await will pause execution in the async function, until the awaited Promise resolves. Using await doesn't block the main thread like a synchronous operation would, but pauses execution within the async function where it is used. Once the Promise resolves, execution will begin again where it left off.

The await keyword can only be used inside an async function. It can't be used in the global context and must enclose it in an async function.

Error Handling with async/await

Error handling in async/await comes with a big improvement. When an error or an exception is thrown, it will reference the origin of the error (the function it originated from). Hence, the context of the call is not lost, and the stack trace can be used to debug easier.

Error are handled by wrapping the await calls in a try/catch block, instead of using .catch.

Let's add error handling to the example from above:

const fetch = require('node-fetch');

async function run() {
  try {
    const status = await fetch(
      'https://jsonplaceholder.typicode.com/todos/1',
    )
      .then(response => response.json())
      .then(res => res);
    console.log(status, 'Complete!');
  } catch (error) {
    console.log(error);
  }
}
run();

An async function return a Promise implicitly, so handling errors with a catch handler would also be possible. Though handling errors with a try/catch block is the common way of doing it, so the error handling is not delegated to the outside of async function.

const fetch = require('node-fetch');

async function run() {
  const status = await fetch(
    'https://jsonplaceholder.typicode.com/todos/1',
  )
    .then(response => response.json())
    .then(res => res);
  console.log(status, 'Complete!');
}

run.catch(error => console.log(error));

TL;DR

  • async/await is the modern standard for asynchronous code in Node.js
  • Using the async and await keywords can further simplify code and remove nested Promises.
  • Asynchronous code looks and behaves similar to synchronous code without blocking the Node.js Event Loop.

Thanks for reading and if you have any questions, use the comment function or send me a message @mariokandut.

If you want to know more about Node, have a look at these Node Tutorials.

References (and Big thanks):

HeyNode, MDN, MDN Async Function

More node articles:

How to create a web server in Node.js

How to dynamically load ESM in CJS

How to convert a CJS module to an ESM

How to create a CJS module

How to stream to an HTTP response

How to handle binary data in Node.js?

How to use streams to ETL data?

How to connect streams with pipeline?

How to handle stream errors?

How to connect streams with pipe?

What Is a Node.js Stream?

Handling Errors in Node (asynchronous)

Handling Errors in Node.js (synchronous)

Introduction to errors in Node.js

Callback to promise-based functions

ETL: Load Data to Destination with Node.js

ETL: Transform Data with Node.js

ETL: Extract Data with Node.js

Event Emitters in Node.js

How to set up SSL locally with Node.js?

How to use async/await in Node.js

What is an API proxy?

How to make an API request in Node.js?

How does the Event Loop work in Node.js

How to wait for multiple Promises?

How to organize Node.js code

Understanding Promises in Node.js

How does the Node.js module system work?

Set up and test a .env file in Node

How to Use Environment Variables in Node

How to clean up node modules?

Restart a Node.js app automatically

How to update a Node dependency - NPM?

What are NPM scripts?

How to uninstall npm packages?

How to install npm packages?

How to create a package.json file?

What Is the Node.js ETL Pipeline?

What is data brokering in Node.js?

How to read and write JSON Files with Node.js?

What is package-lock.json?

How to install Node.js locally with nvm?

How to update Node.js?

How to check unused npm packages?

What is the Node.js fs module?

What is Semantic versioning?

The Basics of Package.json explained

How to patch an NPM dependency

What is NPM audit?

Beginner`s guide to NPM

Getting started with Node.js

Scroll to top ↑