Promise.any()
Fulfills with the first promise to succeed, ignoring rejections until every input has failed.
Promise.any(iterable)- Added in JavaScript ES2021
Parameters
| Parameter | Type | Description |
|---|---|---|
$iterable | Iterable | An iterable, such as an Array, of promises. Values are awaited, so other thenables are resolved too; non-thenables are passed through as-is. |
Return value
PromiseA Promise that fulfills with the value of the first input to fulfill. It rejects with an AggregateError if every input rejects, and is already rejected if the iterable is empty.
Errors
Rejects (rather than throws) with an AggregateError whose errors property holds every rejection reason in input order. TypeError if the argument is not iterable.
Promise.any() is the optimist of the combinators: it wants one success and tolerates any number of failures on the way there. It fulfills as soon as the first input fulfills and ignores every rejection unless all of them reject.
The AggregateError
When everything fails, the rejection reason is a single AggregateError whose errors property is an array of all the individual reasons, in input order rather than failure order. Reading err.message alone gives you a generic string like "All promises were rejected" — the diagnosis you actually want is in err.errors.
any() versus race()
Both settle early, but on different criteria. race() settles on the first promise to settle, so a fast rejection wins and rejects the whole thing. any() settles on the first promise to fulfill, so a fast rejection is simply skipped. Reach for any() when you have several ways to get the same answer and only need one to work.
Edge case
An empty iterable rejects immediately with an AggregateError holding an empty errors array — the mirror image of Promise.all([]), which fulfills.
Example
When to use it
- Query several mirrors and use whichever responds successfully first
- Fall back from cache to database to backup without nesting catch blocks
- Race redundant endpoints where some are expected to be down
- Collect every failure reason in one place when no source works
Frequently asked questions
What is the difference between Promise.any and Promise.race?
any() waits for the first fulfillment and ignores rejections unless all inputs reject; race() settles with the first result of any kind, so an early rejection rejects the whole thing.
How do I read the individual errors from Promise.any?
Access the errors property on the AggregateError: catch(e => e.errors) gives an array of every rejection reason, in the order the promises were passed.
What does Promise.any([]) do?
It rejects immediately with an AggregateError whose errors array is empty, because there was never any input that could fulfill.
More examples
Empty input, and non-promise values
The empty iterable rejects straight away with an AggregateError carrying zero errors. In the second call the plain string counts as an immediately fulfilled value, so it wins over the rejection beside it.
try {
await Promise.any([]);
} catch (e) {
console.log("empty:", e.name, e.errors.length);
}
console.log(await Promise.any([Promise.reject(new Error("r")), "plain"]));any() versus race() on the same inputs
Identical inputs, opposite outcomes. any() skips the 5ms rejection and waits for the 20ms success; race() takes the 5ms rejection because it was simply first to settle.
const boom = (ms, m) => new Promise((_, rj) => setTimeout(() => rj(new Error(m)), ms));
const delay = (ms, v) => new Promise((r) => setTimeout(() => r(v), ms));
const list = () => [boom(5, "early failure"), delay(20, "eventual success")];
console.log("any ->", await Promise.any(list()));
console.log("race ->", await Promise.race(list()).catch((e) => "rejected: " + e.message));
Discussion