Understanding Promise.any() in JavaScript

Rohit DasuRohit Dasu
3 min read

Introduction

The Promise.any() static method takes an iterable of promises as input and returns a single Promise. This returned promise fulfills when any of the input promises fulfills, with the value of the first fulfilled promise. It rejects when all of the input promises reject (including when an empty iterable is passed), with an AggregateError containing an array of rejection reasons.

When should you use it?

When your frontend only needs one fulfilled value, it doesn't wait for other promises. Once one promise is fulfilled, it returns the fulfilled value directly, not as part of an array.

Case #1: The fastest promise is printed

function simulateApiCall(success, time = 0, value) { // helps simulate an api call
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if(success) {
                resolve(value); // resolving by passing the value argument
            } else {
                reject(value); // rejecting by passing the value argument
            }
        }, time) // adding a pause of `time` ms
    });
}

const api1 = simulateApiCall(true, 1000, 'data1');
const api2 = simulateApiCall(true, 3000, 'data2');
const api3 = simulateApiCall(true, 200, 'data3');

const arrayOfPromises = [api1, api2, api3]; // creating array of promises

Promise.any(arrayOfPromises).then((response) => {
    console.log('success', response); // printing on success
}).catch((error) => {
    console.log('failed', error); // printing on error
});

// output: success data3

In the above example, I created a function called simulateApiCall() to mimic an API call. I made three promises using this function and stored them in an array named arrayOfPromises. I then passed this array to the Promise.any method. When the fastest promise was fulfilled, a success message was printed with the resolved data. In this case, the api3 promise is the fastest because it has the shortest time value, so its value is printed.

Case #2: If no promise is fulfilled

const api1 = simulateApiCall(false, 1000, 'data1'); // success = false
const api2 = simulateApiCall(false, 3000, 'data2'); // success = false
const api3 = simulateApiCall(false, 200, 'data3'); // success = false
// passing `false` to the `success` argument

const arrayOfPromises = [api1, api2, api3]; // creating array of promises

Promise.any(arrayOfPromises).then((response) => {
    console.log('success', response); // printing on success
}).catch((error) => {
    console.log('failed', error); // printing on error
});

// output: failed [AggregateError: All promises were rejected] {
//  [errors]: [ 'data1', 'data2', 'data3' ]
// }

Here, to show an error response, I've set all the promises to be rejected (by passing false to the success argument in the simulateApiCall function). As a result, we got a failed response with an AggregateError containing an array of rejection reasons.

Case #3: Empty array is passed to the Promise.any method

const arrayOfPromises = [];

Promise.any(arrayOfPromises).then((response) => {
    console.log('success', response); // printing on success
}).catch((error) => {
    console.log('failed', error); // printing on error
});

// output: failed
// [AggregateError: All promises were rejected] { [errors]: [] }

As expected, we received an AggregateError response when we passed an empty array to the Promise.any method. Since the empty array doesn't have any rejection values, it prints a blank array in the AggregateError.

Case #4: Passing non-promise values in the array

const arrayOfPromises = [ 12, 30 ];

Promise.any(arrayOfPromises).then((response) => {
    console.log('success', response); // printing on success
}).catch((error) => {
    console.log('failed', error); // printing on error
});

// output: success 12

Here we see a special case. Even if we don't provide an array of promises, it still shows success and displays the resolved value. In this example, I provided two non-promise values. It returned the first success result as 12 because it was the first value in the array.

Thanks for reading till this, visit my portfolio: rohitdasu.dev

This article explores the behaviour of the Promise.any method in JavaScript through various examples. It demonstrates how Promise.any handles an empty array, resulting in an AggregateError with no rejection values. Additionally, it shows a unique case where non-promise values in the array still lead to a successful resolution, returning the first value in the array.

0
Subscribe to my newsletter

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

Written by

Rohit Dasu
Rohit Dasu

A Developer's Journey of Thought and Discovery