Promise.allLoading saved progress…

Promise.all

Implement your own version of Promise.all. You take an iterable of promises (or plain values), kick them all off in parallel, and return a single promise that resolves with an array of their results — in input order — or rejects as soon as any of them rejects.

Signature

// Returns a Promise that fulfils with results[] in input order,
// or rejects with the reason of the first input to reject.
function promiseAll<T>(iterable: Iterable<T | PromiseLike<T>>): Promise<T[]>;

Examples

promiseAll([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)])
  .then(console.log); // [1, 2, 3]
// Non-promise values pass through. Order is preserved regardless of timing.
const slow = new Promise((r) => setTimeout(() => r('slow'), 30));
const fast = Promise.resolve('fast');
promiseAll([slow, fast, 42]).then(console.log); // ['slow', 'fast', 42]
// First rejection wins. The 'b' that resolves later is discarded.
const ok = new Promise((r) => setTimeout(() => r('a'), 50));
const bad = Promise.reject('boom');
promiseAll([ok, bad]).catch(console.log); // 'boom'
// Empty iterable resolves to [] on the next microtask.
promiseAll([]).then(console.log); // []

Notes

  • Index, not settle order. results[i] must correspond to the i-th input, even if that input was the slowest to settle. Don't .push() results as they arrive.
  • First rejection short-circuits. As soon as any input rejects, the returned promise rejects with that reason. Later fulfilments or rejections must be ignored — don't call resolve or reject twice.
  • Non-promise inputs pass through. 42, 'hello', null, plain objects, and thenables (any object with a .then method) are all valid inputs. Wrap them with Promise.resolve so the same code path handles every case.
  • Iterate the input once. The iterable might be a generator that can't be re-iterated. A single for...of is the right shape.
  • Synchronous throws from the iterator reject the result. If the iterable's next() throws (or Symbol.iterator itself does), the returned promise rejects with that error rather than throwing synchronously to the caller.
  • Always return a real Promise — not the input, not a thenable. Tests check instanceof Promise.
  • Don't use Promise.all to implement promiseAll. That defeats the exercise. You may use new Promise(...), Promise.resolve, and .then.
Loading editor…