Async & Await in JavaScript

6 min read·Jan 1, 2025

The async and await keywords are used to work with asynchronous code in a more synchronous manner. They eliminate the need for complex chaining and nested then() blocks by flattening the flow into a synchronous-looking structure.

They also simplify error handling by centralizing rejected promises in a try...catch block, ultimately making the code more linear and easier to follow.

Declaring asynchronous functions

An asynchronous function is a function that returns a promise and is declared using the async keyword:

async function functionName(parameters?) {
  //
}

Note: Any value returned from an async function using the return statement will be automatically wrapped in a resolved promise.

Awaiting for promises

When used within an async function, the await keyword allows you to pause the execution of the function and wait until a promise resolves or rejects:

async function functionName(parameters?) {
  try {
    let result? = await Promise;
    // process result
  } catch(error) {
    // process error
  }
}

Tip: You should always wrap the await keyword in a try...catch block, as if the promise is rejected, the await expression will throw the rejected value.

Example

Let's consider this script, that implements an asynchronous retry mechanism:

function fetchData() {
  const success = Math.random() < 0.5;

  return (success)
    ? Promise.resolve({ message: 'success' })
    : Promise.reject(new Error('network_error'));
}

async function fetchWithRetry(retries = 3) {
  for (let attempt = 1; attempt <= retries; attempt++) {
    try {
      return await fetchData();
    } catch (error) {
      if (attempt === retries) {
        throw error;
      }
      console.log(`Retrying... (${attempt}/${retries})`);
    }
  }
}

fetchWithRetry()
  .then(console.log)
  .catch(console.error);

When executed, it will:

  1. Define a function named fetchData() that randomly returns a resolved or rejected promise.

  2. Define a function named fetchWithRetry() that calls the fetchData() function and either returns its value in case of a resolved promise, or retries it up to 3 times before re-throwing the error.

  3. Output the value returned by the promise.

Which will produce this output:

Retrying... (1/3)
{ message: 'success' }

Enjoying the courses?

I've made these courses completely free so anyone can learn from them. If they've helped you and you'd like to actively support the work behind BackendBrewery, you can leave a tip:

Support BackendBrewery
Async & Await in JavaScript | Backend Brewery