Promise Combinators

Difficulty: Intermediate

Question

What are the four Promise combinator methods? When would you use each?

Answer

Promise.all(promises): resolves when ALL resolve, rejects immediately on any rejection. Use when you need all results and one failure should cancel all.

Promise.allSettled(promises): waits for ALL to settle. Returns array of { status, value/reason }. Use when you want all results regardless of failures.

Promise.race(promises): resolves/rejects with the first to settle. Use for timeouts or first-to-respond patterns.

Promise.any(promises): resolves with the first successful promise. Rejects only if ALL reject (AggregateError). Use when any one success is enough.

Code examples

Promise.all vs Promise.allSettled

const fetchUser = () => Promise.resolve({ id: 1, name: 'Alice' });
const fetchPosts = () => Promise.resolve([{ id: 1 }]);
const fetchBroken = () => Promise.reject(new Error('Network error'));

try {
  const [user, posts] = await Promise.all([
    fetchUser(),
    fetchPosts(),
    fetchBroken()
  ]);
} catch (e) {
  console.log(e.message);
}

const results = await Promise.allSettled([
  fetchUser(),
  fetchPosts(),
  fetchBroken()
]);

results.forEach(result => {
  if (result.status === 'fulfilled') {
    console.log('Success:', result.value);
  } else {
    console.log('Failed:', result.reason.message);
  }
});

Promise.all short-circuits on first failure. Promise.allSettled always waits for all and provides status for each.

Promise.race and Promise.any

function timeout(ms) {
  return new Promise((_, reject) =>
    setTimeout(() => reject(new Error(`Timeout after ${ms}ms`)), ms)
  );
}

try {
  const result = await Promise.race([
    fetch('/api/data').then(r => r.json()),
    timeout(3000)
  ]);
  console.log('Result:', result);
} catch (e) {
  console.log(e.message);
}

const servers = ['https://s1.api.com', 'https://s2.api.com', 'https://s3.api.com'];

try {
  const fastestResponse = await Promise.any(
    servers.map(url => fetch(url).then(r => r.json()))
  );
  console.log('Fastest:', fastestResponse);
} catch (e) {
  console.log('All failed:', e.errors);
}

Promise.race is ideal for timeouts. Promise.any is ideal for redundant requests - use whichever server responds first successfully.

Key points

Concepts covered

Promise.all, Promise.allSettled, Promise.race, Promise.any, Concurrency