Handling Asynchronous Code in JavaScript with Promises

Hazrat AliHazrat Ali
4 min read

Understanding the Promise API in JavaScript

Table of contents

Show less

Understanding the Promise API in JavaScript

The Promise API in JavaScript provides methods to handle multiple promises concurrently. These methods—Promise.all(), Promise.allSettled(), Promise.race(), and Promise.any()—are powerful tools for managing asynchronous operations. Let’s explore each in detail.


1. Promise.all()

The Promise.all() method takes an iterable (e.g., an array) of promises and returns a single promise that:

  • Resolves when all the promises in the array have resolved.

  • Rejects if any of the promises in the array reject, returning the reason for the first rejected promise.

Use Case

Use Promise.all() when you need all promises to succeed, and their results can be used collectively.

Syntax

Copy

Promise.all([promise1, promise2, ...])
  .then(results => {
    // All promises resolved
    console.log(results);
  })
  .catch(error => {
    // At least one promise rejected
    console.error(error);
  });

Example

Copy

const promise1 = Promise.resolve(10);
const promise2 = Promise.resolve(20);
const promise3 = Promise.resolve(30);

Promise.all([promise1, promise2, promise3])
  .then(results => console.log(results)) // Output: [10, 20, 30]
  .catch(error => console.error(error));

const failingPromise = Promise.reject("Error!");

Promise.all([promise1, failingPromise])
  .then(results => console.log(results))
  .catch(error => console.error(error)); // Output: Error!

2. Promise.allSettled()

The Promise.allSettled() method takes an iterable of promises and returns a single promise that:

  • Resolves when all promises settle (i.e., resolve or reject).

  • Provides an array of objects, each describing the outcome of each promise (status and value or reason).

Use Case

Use Promise.allSettled() when you need to know the outcome of all promises, regardless of whether they resolve or reject.

Syntax

Copy

Promise.allSettled([promise1, promise2, ...])
  .then(results => {
    console.log(results);
  });

Example

Copy

const promise1 = Promise.resolve(10);
const promise2 = Promise.reject("Error!");
const promise3 = Promise.resolve(30);

Promise.allSettled([promise1, promise2, promise3])
  .then(results => console.log(results));
/*
Output:
[
  { status: 'fulfilled', value: 10 },
  { status: 'rejected', reason: 'Error!' },
  { status: 'fulfilled', value: 30 }
]
*/

3. Promise.race()

The Promise.race() method takes an iterable of promises and returns a single promise that:

  • Settles (resolves or rejects) as soon as the first promise settles (whichever happens first).

Use Case

Use Promise.race() when you are interested in the fastest promise, regardless of whether it resolves or rejects.

Syntax

Copy

Promise.race([promise1, promise2, ...])
  .then(result => {
    // First promise to settle
    console.log(result);
  })
  .catch(error => {
    console.error(error);
  });

Example

Copy

const promise1 = new Promise(resolve => setTimeout(() => resolve("First!"), 100));
const promise2 = new Promise(resolve => setTimeout(() => resolve("Second!"), 200));

Promise.race([promise1, promise2])
  .then(result => console.log(result)) // Output: "First!"
  .catch(error => console.error(error));

const failingPromise = new Promise((_, reject) => setTimeout(() => reject("Error!"), 50));

Promise.race([failingPromise, promise1])
  .then(result => console.log(result))
  .catch(error => console.error(error)); // Output: "Error!"

4. Promise.any()

The Promise.any() method takes an iterable of promises and returns a single promise that:

  • Resolves as soon as the first promise resolves.

  • Rejects only if all promises reject, with an AggregateError containing the rejection reasons.

Use Case

Use Promise.any() when you need the first successful result and can ignore failures.

Syntax

Copy

Promise.any([promise1, promise2, ...])
  .then(result => {
    console.log(result);
  })
  .catch(error => {
    console.error(error);
  });

Example

Copy

const promise1 = Promise.reject("Error 1");
const promise2 = Promise.reject("Error 2");
const promise3 = Promise.resolve(30);

Promise.any([promise1, promise2, promise3])
  .then(result => console.log(result)) // Output: 30
  .catch(error => console.error(error));

const allFailing = [Promise.reject("Error A"), Promise.reject("Error B")];

Promise.any(allFailing)
  .then(result => console.log(result))
  .catch(error => console.error(error)); 
/*
Output: AggregateError: All promises were rejected
*/

Comparison of Promise Methods

Method

When Does It Resolve?

When Does It Reject?

Use Case

Promise.all()

When all promises resolve

If any promise rejects

Wait for all promises to resolve successfully

Promise.allSettled()

When all promises settle

Never

Get the outcome (fulfilled/rejected) of all promises

Promise.race()

As soon as the first promise settles

If the first settled promise rejects

Use the result of the first promise to settle, regardless of resolution or rejection

Promise.any()

As soon as the first promise resolves

If all promises reject

Return the first successful result; ignore rejections


Conclusion

Understanding the Promise API is crucial for handling asynchronous operations in JavaScript effectively. Each method serves a specific purpose:

  • Use Promise.all() for aggregating results when all promises succeed.

  • Use Promise.allSettled() for handling both successes and failures collectively.

  • Use Promise.race() to act on the fastest promise.

  • Use Promise.any() to retrieve the first successful promise while ignoring rejections.

Master these methods, and you’ll be well-equipped to manage complex async tasks in your projects.🚀

0
Subscribe to my newsletter

Read articles from Hazrat Ali directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Hazrat Ali
Hazrat Ali

Hello, I'm Hazrat Ali, a dedicated Software Developer with a passion for crafting robust and innovative solutions.