DMarlon Studio

Lesson 13 · 13 of 20

Promise.all, allSettled and race · JavaScript

Run several async tasks at once in JavaScript and combine their results with Promise.all, allSettled, race and any.

JavaScript · Promise.all, allSettled and race in DMarlon Studio: the example's code and its output in the terminal

When you have several independent async tasks, there is no need to wait for them one by one. `Promise.all` starts them together and waits for all of them: the product page takes as long as the slowest service (60 ms), not the sum of all three. Results come back in array order, not in the order they finished: prices comes first even though it was the last to arrive.

Promise.all is all-or-nothing: as soon as one promise rejects, the whole thing rejects with that error, without waiting for the rest. That is why payments failed reaches the catch after 10 ms.

`Promise.allSettled` never rejects: it waits for every promise and returns a report for each one, with status set to fulfilled (plus its value) or rejected (plus its reason). Use it when you need to know what failed without losing what worked, such as sending notifications by email and SMS.

`Promise.race` settles with the first promise to finish, successfully or not: handy for picking the fastest server or adding a time limit. `Promise.any` takes the first one that fulfils and ignores failures: even though cache fails after 5 ms, database wins. Each service uses a different delay so the result is always the same.

Code · main.js

// A fake service that answers (or fails) after a fixed delay in ms.function service(name, ms, ok = true) {  return new Promise((resolve, reject) =>    setTimeout(() => (ok ? resolve(`${name} ${ms}ms`) : reject(new Error(`${name} failed`))), ms)  );}async function main() {  // all: waits for every promise; results keep the order of the array.  const page = await Promise.all([service("prices", 60), service("stock", 20), service("reviews", 40)]);  console.log("all:", page.join(" | "));  // all rejects as soon as one of the promises rejects.  try {    await Promise.all([service("prices", 30), service("payments", 10, false)]);  } catch (err) {    console.log("all rejected:", err.message);  }  // allSettled: never rejects; it reports the outcome of each one.  const sent = await Promise.allSettled([service("email", 20), service("sms", 10, false)]);  for (const r of sent) console.log("allSettled:", r.status, "-", r.value ?? r.reason.message);  // race: the first promise to settle wins, fulfilled or rejected.  const fastest = await Promise.race([service("mirror-eu", 50), service("mirror-us", 15)]);  console.log("race winner:", fastest);  // any: the first one to fulfil wins; failures are ignored.  const firstOk = await Promise.any([service("cache", 5, false), service("database", 25)]);  console.log("any:", firstOk);}main();

Output · node main.js

all: prices 60ms | stock 20ms | reviews 40ms
all rejected: payments failed
allSettled: fulfilled - email 20ms
allSettled: rejected - sms failed
race winner: mirror-us 15ms
any: database 25ms

Key points

  • Promise.all waits for all and keeps order; a single failure rejects it.
  • Promise.allSettled reports each outcome and never rejects.
  • Promise.race returns the first to settle, fulfilled or rejected.
  • Promise.any returns the first to fulfil.

Exercise

Write a withTimeout(promise, ms) function that uses Promise.race with a promise that rejects after ms milliseconds, and test it with service("prices", 60) and a 30 ms limit.