DEV Community

Hamza Khan
Hamza Khan

Posted on

2 1

πŸ”„ Async/Await vs Promise.all() β€” When to Use What?

Asynchronous JavaScript has come a long wayβ€”from callback hell to Promises and now the elegant async/await syntax. But even in modern code, developers often ask:

β€œShould I use async/await or Promise.all()?”

Let’s settle the debate with clear examples, performance comparisons, and best practices in 2025.

🧠 The Core Difference

  • async/await: Executes asynchronous operations sequentially, unless used with Promise.all.
  • Promise.all(): Executes multiple promises in parallel and waits for all of them to resolve (or reject).

⚑ Sequential vs Parallel

Let’s say you need to make 3 API calls.

❌ Sequential Execution (async/await)

const getData = async () => {
  const a = await fetchDataA(); // wait
  const b = await fetchDataB(); // wait
  const c = await fetchDataC(); // wait
  return [a, b, c];
};
Enter fullscreen mode Exit fullscreen mode

Time taken β‰ˆ fetchDataA + fetchDataB + fetchDataC

βœ… Parallel Execution (Promise.all)

const getData = async () => {
  const [a, b, c] = await Promise.all([
    fetchDataA(),
    fetchDataB(),
    fetchDataC(),
  ]);
  return [a, b, c];
};
Enter fullscreen mode Exit fullscreen mode

Time taken β‰ˆ max(fetchDataA, fetchDataB, fetchDataC)

🧠 Use Promise.all() when tasks are independent and can run in parallel.

πŸ’₯ What About Errors?

Promise.all() Fails Fast:

try {
  const [a, b] = await Promise.all([failingFunc(), successFunc()]);
} catch (err) {
  console.error('At least one failed:', err);
}
Enter fullscreen mode Exit fullscreen mode

If any promise rejects, the entire Promise.all() rejects.

Want All Results No Matter What? Use Promise.allSettled():

const results = await Promise.allSettled([
  mightFail1(),
  mightFail2(),
]);

results.forEach((result) => {
  if (result.status === 'fulfilled') console.log(result.value);
  else console.error(result.reason);
});
Enter fullscreen mode Exit fullscreen mode

πŸ” Looping with Async Ops

Here’s where async/await shines: inside loops.

❌ Not Ideal

for (const user of users) {
  await sendEmail(user); // sequential, slow
}
Enter fullscreen mode Exit fullscreen mode

βœ… Better: Use Promise.all with .map()

await Promise.all(users.map(user => sendEmail(user)));
Enter fullscreen mode Exit fullscreen mode

πŸš€ This sends emails in parallel. Much faster.

🧠 TL;DR β€” When to Use What?

Use Case Use async/await Use Promise.all()
Tasks must run sequentially βœ… ❌
Tasks are independent ❌ βœ…
You need all results, even fails ❌ βœ… Promise.allSettled()
Error handling per task βœ… ❌
Inside a loop βœ… (small data) βœ… .map() + Promise.all for large data

πŸ§ͺ Bonus: Performance Benchmark

For I/O-bound operations like API calls or DB queries, parallel execution with Promise.all() significantly improves response time. For CPU-bound tasks, consider using Web Workers or moving to a language like Go or Rust.

✨ Final Thoughts

In 2025, writing performant async code is less about picking one method and more about understanding concurrency.

  • βœ… Use async/await for readability.
  • βœ… Use Promise.all() for speed.
  • βœ… Combine both when necessary!

DevCycle image

Ship Faster, Stay Flexible.

DevCycle is the first feature flag platform with OpenFeature built-in to every open source SDK, designed to help developers ship faster while avoiding vendor-lock in.

Start shipping

Top comments (0)

SurveyJS custom survey software

JavaScript UI Library for Surveys and Forms

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

View demo