tryjs.app

JavaScript Promise.all — Run Async Operations in Parallel

Try JavaScript Promise.all with runnable examples. Start async operations in parallel, collect their results and handle rejected promises with try/catch.

Promise.all

Run async operations in parallel

javascriptAsync Patterns
const delay = (ms, val) =>
  new Promise(resolve => setTimeout(() => resolve(val), ms));

(async () => {
  // Parallel — ~200ms total
  console.time("parallel");
  const results = await Promise.all([
    delay(100, "first"),
    delay(200, "second"),
    delay(50, "third"),
  ]);
  console.timeEnd("parallel");
  console.log("results:", results);

  // Same work serially — ~350ms total
  console.time("serial");
  const a = await delay(100, "first");
  const b = await delay(200, "second");
  const c = await delay(50, "third");
  console.timeEnd("serial");
  console.log([a, b, c]);
})();

Overview

Promise.all takes an iterable of promises and returns a single promise that resolves when all of them have resolved. Results come back as an array in the same order as the input, regardless of which one finished first. If any input promise rejects, Promise.all rejects immediately with that error — the other promises keep running but their results are discarded.

How It Works

Fire first, await once

Start all the async operations before you await. This is the trick: const [a, b, c] = await Promise.all([fetchA(), fetchB(), fetchC()]) runs them in parallel. Writing three awaits in sequence runs them serially.

Results are ordered, not finish-ordered

The result array is in the same order as the input, not the order they completed. If fetchC finishes first, it still ends up at results[2].

Fail-fast semantics

The first rejection causes Promise.all to reject immediately. Other promises keep running in the background but their results are ignored. Use Promise.allSettled if you want all outcomes, failures included.

Accepts any iterable

Not just arrays — any iterable of promises (or plain values, which are wrapped). Mixed values and promises are both supported.

Common Mistakes

  • Awaiting in a loop instead of Promise.all — turns parallel work serial.
  • Expecting partial results after one promise rejects — Promise.all discards them. Use allSettled.
  • Forgetting that Promise.all starts every promise immediately on construction, before the await — if you meant to rate-limit, you need a queue.
  • Using Promise.all with a huge array (thousands of items) and overwhelming the server — batch or use a concurrency limiter.

When to Use It

Use Promise.all when you have a fixed, small-to-medium number of independent async operations that must all succeed. For unbounded lists, add a concurrency limit. For operations where partial success is acceptable, use Promise.allSettled instead.

Frequently Asked Questions

What does Promise.all do?

Promise.all takes an iterable of promises and returns a single promise that resolves with an array of their results when all have resolved. If any rejects, the whole thing rejects with that error.

Does Promise.all run promises in parallel?

It doesn't start them — you do. Promise.all just waits for a set of already-started promises. Because JavaScript starts each promise as soon as you create it, passing them as an array to Promise.all naturally runs them concurrently.

What happens if one promise in Promise.all rejects?

Promise.all rejects immediately with that error. Any other promises keep running but their results are discarded. If you need all outcomes regardless, use Promise.allSettled instead.

Is Promise.all faster than await in a loop?

Yes, dramatically — if the operations are independent. await in a loop runs them one after another; Promise.all runs them concurrently. A 10-item loop of 100ms operations takes ~1000ms serially and ~100ms with Promise.all.