Understanding Promise.any() in JavaScript
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.
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