Compile Ready
Module 9 · Promises

Promise.any

Advanced12m read10m practice22m total
PromisesCombinatorsAggregateErrorFirst Success

Introduction

Promise.any(iterable) is the fastest-success combinator. It fulfils as soon as the first input fulfils and ignores earlier rejections. It rejects only when every input rejects, using an AggregateError containing all rejection reasons.

Why This Matters

Promise.any is easy to confuse with Promise.race. The interview distinction is that any wants the first fulfillment, while race wants the first settlement. A fast rejection can win race, but it cannot win any unless all inputs reject.

Theory

Exact semantics

Promise.any accepts an iterable of values, promises, or thenables. Plain values count as fulfilled inputs, so a plain value can make Promise.any fulfil.

It fulfils with the value from the first input that fulfils in time. Rejections before that are collected but do not reject the combined promise.

It rejects only if every input rejects. The rejection reason is an AggregateError, and error.errors contains the individual rejection reasons in input order. For an empty iterable, there is no possible fulfillment, so it rejects with an AggregateError whose errors array is empty.

Like other combinators, it does not cancel slower inputs after a winner fulfils.

Combinator comparison

CombinatorFulfils whenRejects whenResult shapeTypical use
Promise.allEvery input fulfilsFirst input rejectsArray of values in input orderAll-or-nothing parallel work
Promise.anyFirst input fulfilsEvery input rejectsFirst fulfilled value or AggregateErrorRedundant sources, fastest success
Promise.allSettledEvery input settlesNever because of input rejectionArray of status objects in input orderPartial success reporting
Promise.raceFirst input fulfils if it settles firstFirst input rejects if it settles firstFirst settled value or reasonTimeouts, first signal wins

When to use it

Use Promise.any when you have multiple acceptable sources: fastest cache, fastest CDN mirror, primary and fallback providers, or redundant replicas. Do not use it when a fast rejection should fail the whole operation; use Promise.race or direct chaining for that.

Visual Diagrams

First fulfillment wins
A rejects early --------- ignored for now
B fulfils next ---------- Promise.any fulfils with B
C fulfils later --------- ignored by combined promise

Only if A, B, and C all reject does Promise.any reject.

Rejections are tolerated until no candidates remain.

All rejected produces AggregateError
inputs: [ A, B, C ]
A rejects with reasonA
B rejects with reasonB
C rejects with reasonC

Promise.any rejects with AggregateError
errors: [ reasonA, reasonB, reasonC ]

The `errors` array follows input order, not rejection order.

Code Examples

Use the first successful mirror

A fast failure is ignored because another source may still fulfil.

Loading…

Inspect AggregateError

When every input rejects, you can inspect all failure reasons.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1function candidate(label, ms, shouldFulfill) {
2 return new Promise(function (resolve, reject) {
3 setTimeout(function () {
4 console.log(label);
5 if (shouldFulfill) {
6 resolve(label);
7 } else {
8 reject(label);
9 }
10 }, ms);
11 });
12}
13
14Promise.any([
15 candidate('A reject', 10, false),
16 candidate('B fulfill', 30, true),
17 candidate('C fulfill', 20, true),
18]).then(function (value) {
19 console.log('any ' + value);
20});

Predict the output #2

javascript
1Promise.any([
2 Promise.reject('x'),
3 new Promise(function (resolve, reject) {
4 setTimeout(function () {
5 reject('y');
6 }, 0);
7 }),
8]).catch(function (error) {
9 console.log(error.name);
10 console.log(error.errors.join(','));
11});
12
13console.log('sync');

Coding Exercises

Implement a mini Promise.any

Hard

Implement promiseAny(iterable): fulfil with the first fulfilled input, ignore rejections until all inputs reject, reject empty input with AggregateError, and preserve final rejection reasons in input order.

Interview Questions

1How is `Promise.any` different from `Promise.race`?

Promise.any fulfils with the first fulfilled input and ignores rejections unless every input rejects. Promise.race settles with the first input to settle, whether fulfilled or rejected. A fast rejection rejects race but does not reject any while another input can still fulfil.

Asked at:GoogleMetaAmazon

Follow-ups

  • What error does `Promise.any` reject with?
  • Does `Promise.any` cancel slower inputs after success?
2What happens when every input to `Promise.any` rejects?

The returned promise rejects with an AggregateError. The errors property contains all rejection reasons in input order. Empty input also rejects with AggregateError because there is no possible fulfillment.

Quiz

1. Which input outcome makes `Promise.any` fulfil?

2. If every input to `Promise.any` rejects, the returned promise rejects with...

Summary

  • `Promise.any` fulfils with the first fulfilled input.
  • Early rejections are ignored unless every input rejects.
  • If all inputs reject, it rejects with `AggregateError` containing reasons in input order.
  • Use it for redundant sources where any successful result is acceptable.

Cheat Sheet

Use when: fastest successful result wins.

Fulfil: first fulfillment by time.

Reject: only if all inputs reject → AggregateError.

Errors: error.errors preserves input order.

Empty: rejects with AggregateError.

Not race: fast rejection does not win unless all reject.