← Back to JavaScript Course | Chapter 4: Modern JS, Async & DOM | Lesson 24 of 26

JS Async Parallel

Awaiting several independent async operations one after another wastes time unnecessarily, when they could run at the same time instead -- Promise.all() (and its relatives) let you kick off multiple async operations in parallel and wait for all of them together, dramatically reducing total wait time.
Syntax
javascript
const results = await Promise.all([promise1, promise2]);
await Promise.allSettled([promise1, promise2]);
await Promise.race([promise1, promise2]);

The Problem with Sequential Awaiting

Awaiting one async operation, then starting and awaiting the next, and so on, means the TOTAL time is the SUM of every individual operation's time -- if three independent operations each take one second, sequential awaiting takes three seconds total, even though none of them actually depended on each other.

Note: Before awaiting several operations one after another, ask whether any of them actually depend on a previous one's result -- if not, they are strong candidates for running in parallel instead.
Warning: Sequentially awaiting operations that have no actual dependency on each other is a common, easy-to-miss performance mistake in async code.

उदाहरण: The Problem with Sequential Awaiting

javascript
async function sequential() {
  const a = await new Promise(r => setTimeout(() => r(1), 1000));
  const b = await new Promise(r => setTimeout(() => r(2), 1000));
  console.log(a, b); // takes ~2 seconds total
}
sequential();

Running in Parallel with Promise.all()

Promise.all([promise1, promise2, ...]) starts every promise in the array immediately (they run concurrently, not one after another), and resolves once all of them have succeeded, with an array of their results in the same order they were passed in.

Note: Start every independent async operation first (without awaiting each individually), collect them into an array, and pass that array to Promise.all() to run them together.
Warning: Promise.all() rejects immediately the moment ANY single promise in the array rejects, even if the others are still pending -- you lose visibility into whichever of the others might have succeeded.

उदाहरण: Running in Parallel with Promise.all()

javascript
async function parallel() {
  const [a, b] = await Promise.all([
    new Promise(r => setTimeout(() => r(1), 1000)),
    new Promise(r => setTimeout(() => r(2), 1000)),
  ]);
  console.log(a, b); // takes ~1 second total
}
parallel();

Handling Partial Failures with Promise.allSettled()

Unlike Promise.all(), Promise.allSettled() always waits for every promise to finish, regardless of individual success or failure -- each result in the returned array has a status field ("fulfilled" or "rejected") plus either a value or a reason, letting you handle mixed outcomes gracefully.

Note: Use Promise.allSettled() specifically when partial failure is acceptable and you want to know the outcome of every operation, not just fail everything at the first rejection.
Warning: Promise.allSettled() never itself rejects -- checking each individual result's status field is necessary to detect any failures among the group.

उदाहरण: Handling Partial Failures with Promise.allSettled()

javascript
// Wait for every promise to settle (succeed or fail) before continuing
Promise.allSettled([
  Promise.resolve(1), // resolves immediately with the value 1
  Promise.reject("failed"), // rejects immediately with the reason "failed"
]).then(results => console.log(results)); // results holds a {status, value/reason} object per promise

Racing Operations with Promise.race()

Promise.race([promise1, promise2, ...]) settles (resolves or rejects) as soon as the FIRST promise in the array settles, ignoring whatever the others eventually do -- commonly used to implement a timeout, racing a real operation against a promise that rejects after a fixed delay.

Note: Use Promise.race() to implement a timeout: race your actual operation against a promise that rejects after your desired timeout duration.
Warning: Promise.race() only reports the FIRST settled promise -- the others continue running in the background even though their eventual result is ignored, which is worth being aware of for cleanup purposes.

उदाहरण: Racing Operations with Promise.race()

javascript
// Race two promises; whichever settles first wins, the other is ignored
Promise.race([
  new Promise(r => setTimeout(() => r("data"), 100)), // resolves with "data" after 100ms
  new Promise((_, reject) => setTimeout(() => reject("timeout"), 50)), // rejects with "timeout" after 50ms
]).then(console.log).catch(console.log); // the faster one (the 50ms rejection) wins the race

Choosing the Right Combinator

Promise.all() is right when every operation must succeed for the overall result to be meaningful; Promise.allSettled() is right when partial success is acceptable and you want visibility into every outcome; Promise.race() is right for a "whichever finishes first" scenario like a timeout.

Note: Match the combinator to the actual failure semantics you need: all-or-nothing (all), best-effort (allSettled), or first-to-finish (race).
Warning: Choosing Promise.all() for a scenario where partial success should be acceptable throws away the results of every operation that succeeded, just because one other operation failed.

उदाहरण: Choosing the Right Combinator

javascript
Promise.all([Promise.resolve(1), Promise.resolve(2)]).then(r => console.log("all:", r));
Promise.allSettled([Promise.resolve(1), Promise.reject("x")]).then(r => console.log("settled:", r));
Live Example
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.