Promise.any() in JavaScript

Introduced in ES2021 (ECMAScript 2021). This article explores what Promise.any() is, how it works, and why it is useful.

What is Promise.any()?

Promise.any() is a method that takes an iterable (such as an array) of promises and returns a single promise.

This returned promise is fulfilled as soon as any of the input promises are fulfilled, with the value of the fulfilled promise.

If none of the input promises are fulfilled (i.e., all of them are rejected/fail), it returns a promise that is rejected with an AggregateError, a special type of error that groups multiple individual errors.

How to

To understand how Promise.any() works, let's look at its syntax and a simple example:

const promise1 = Promise.reject('Error 1');
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'Promise 2'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 200, 'Promise 3'));

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

In this example, Promise.any() takes an array of three promises. The first promise is rejected immediately. The second and third promises resolve after 100 and 200 milliseconds, respectively. Promise.any() fulfills with the value from promise2, the first promise to fulfill.

Why Use Promise.any()?

So you might think why the **** would I need that? I know I did when I first saw it.

But it's about when you do not care about the failures of other operations. Maybe when you are doing something like:

  • Fetching Data from Multiple Sources: If you are trying to fetch data from multiple APIs, you can use Promise.any() to get the first successful response, reducing the overall waiting time.
  • Fallback Mechanisms: When you have multiple fallback options, and you want to proceed with the first one that becomes available.

Error Handling

When all promises in the iterable are rejected, Promise.any() rejects with an AggregateError:

const promise1 = Promise.reject('Error 1');
const promise2 = Promise.reject('Error 2');

Promise.any([promise1, promise2])
  .then((value) => console.log(value))
  .catch((error) => {
    console.log(error instanceof AggregateError);  // Output: true
    console.log(error.message);  // Output: "All promises were rejected"
    console.log(error.errors);  // Output: [ 'Error 1', 'Error 2' ]
  });

In this case, the error is an instance of AggregateError, which contains an array of all individual errors from the rejected promises.

JavaScript
Avatar for Niall Maher

Written by Niall Maher

Founder of Codú - The web developer community! I've worked in nearly every corner of technology businesses: Lead Developer, Software Architect, Product Manager, CTO, and now happily a Founder.

Loading

Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.