Compile Ready
Module 9 · Promises

Promise.all

Intermediate13m read11m practice24m total
PromisesCombinatorsParallelismFail Fast

Introduction

Promise.all(iterable) is the fail-fast combinator for independent async work that must all succeed. It observes every input, fulfils with an array of values in input order, and rejects as soon as the first input rejects.

Why This Matters

Promise.all is the default answer for parallel independent work, but interviewers expect exact details: output order is input order, rejection is fail-fast, non-promises are allowed, empty input fulfils with [], and fail-fast does not cancel in-flight work.

Theory

Exact semantics

Promise.all accepts any iterable of values, promises, or thenables. Each input is normalised through promise resolution, so plain values count as already fulfilled.

It fulfils only when every input fulfils. The fulfillment value is an array whose indexes match the input order, not completion order.

It rejects as soon as the first input rejects in time. The rejection reason is that first rejection reason. Other operations are not cancelled; their timers, network work, or side effects may continue even though the combined promise has already rejected.

For an empty iterable, Promise.all([]) returns an already fulfilled promise with [], but attached .then callbacks still run asynchronously as microtasks.

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.all when tasks are independent and the next step requires every result: profile plus permissions, multiple validations that must all pass, or independent calculations. Use Promise.allSettled when partial results are acceptable. If you need cancellation after a failure, build it into the underlying operations separately.

Visual Diagrams

Input order is preserved
inputs:     [ A, B, C ]
settle time:    C first, A second, B third

Promise.all output after all fulfil:
            [ valueA, valueB, valueC ]

Completion order does not change array indexes.

The returned array is indexed like the input iterable.

Fail-fast does not mean cancel-fast
A starts -------- resolves later
B starts ---- rejects first ---- Promise.all rejects with B reason
C starts --------------- resolves later

A and C can still finish because Promise.all only stops waiting.

The combined promise rejects early, but underlying work continues unless separately cancelled.

Code Examples

Parallel work with ordered results

The fastest task can finish first, but the result array still follows input order.

Loading…

Fail-fast rejection

The first rejection rejects the combined promise. Other promises are not cancelled automatically.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1function task(label, ms, shouldReject) {
2 return new Promise(function (resolve, reject) {
3 setTimeout(function () {
4 console.log('settled ' + label);
5 if (shouldReject) {
6 reject(label);
7 } else {
8 resolve(label);
9 }
10 }, ms);
11 });
12}
13
14Promise.all([
15 task('A', 30, false),
16 task('B', 10, true),
17 task('C', 20, false),
18])
19 .then(function (values) {
20 console.log('all ' + values.join(','));
21 })
22 .catch(function (reason) {
23 console.log('catch ' + reason);
24 });

Predict the output #2

javascript
1Promise.all([Promise.resolve('A'), 'B'])
2 .then(function (values) {
3 console.log(values.join(','));
4 });
5
6console.log('sync');

Coding Exercises

Implement a mini Promise.all

Hard

Implement promiseAll(iterable): accept values or promises, preserve input order, resolve to [] for empty input, fulfil only after all inputs fulfil, and reject as soon as the first input rejects.

Interview Questions

1Explain the exact behavior of `Promise.all`.

Promise.all takes an iterable of values or promises and returns a promise. It fulfils when every input fulfils, with values in input order. It rejects as soon as the first input rejects, using that reason. Empty input fulfils with []. It does not cancel other work after a rejection.

Asked at:GoogleAmazonUber

Follow-ups

  • Does completion order affect the result array?
  • What should you use when partial failures are acceptable?
2If one promise in `Promise.all` rejects, what happens to the other promises?

The combined promise rejects immediately with the first rejection reason, but the other promises are not cancelled. They may still fulfil, reject, log, mutate state, or perform side effects. Cancellation must be built into the underlying operations separately.

Quiz

1. What does `Promise.all([slowA, fastB])` return when both fulfil?

2. When does `Promise.all` reject?

Summary

  • `Promise.all` fulfils only when every input fulfils.
  • Its fulfillment array preserves input order, not completion order.
  • It rejects fast on the first rejection reason and does not cancel other work.
  • Use it for all-or-nothing parallel work; use `allSettled` for partial success reporting.

Cheat Sheet

Use when: independent tasks must all succeed.

Fulfil: all inputs fulfil → array in input order.

Reject: first rejection by time.

Empty: fulfils with [].

Values: non-promises are allowed.

Caveat: fail-fast does not cancel in-flight work.