JavaScript
Node.js
Async Await
Promises
Asynchronous Programming

Wait for all different promise to finish nodejs async await

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you need to wait for several asynchronous operations in Node.js, the usual tool is Promise.all. It does not matter that the promises come from different functions or resolve to different values. What matters is whether you want the group to fail fast on the first rejection or whether you want every result, including failures.

Use Promise.all for Concurrent Success-Or-Fail Groups

Promise.all takes an iterable of promises and resolves when all of them resolve. If any one rejects, the whole Promise.all rejects immediately.

javascript
1async function getUser() {
2  return { id: 1, name: "Ana" };
3}
4
5async function getOrders() {
6  return ["A100", "A101"];
7}
8
9async function getSettings() {
10  return { theme: "dark" };
11}
12
13async function main() {
14  const [user, orders, settings] = await Promise.all([
15    getUser(),
16    getOrders(),
17    getSettings(),
18  ]);
19
20  console.log(user, orders, settings);
21}
22
23main().catch(console.error);

These promises are different operations with different result shapes, and that is completely fine. Promise.all returns the results in the same order as the input array.

await Does Not Make Work Sequential by Itself

A common misunderstanding is that using await means everything is serialized. That is true only if you await each promise before creating the next one.

Sequential version:

javascript
const user = await getUser();
const orders = await getOrders();
const settings = await getSettings();

Concurrent version:

javascript
1const userPromise = getUser();
2const ordersPromise = getOrders();
3const settingsPromise = getSettings();
4
5const [user, orders, settings] = await Promise.all([
6  userPromise,
7  ordersPromise,
8  settingsPromise,
9]);

The second version starts all three operations first and then waits for them together. That is usually what people mean by "wait for all promises to finish."

Use Promise.allSettled If You Need Every Outcome

If one failure should not cancel the whole group, use Promise.allSettled. It waits for every promise and gives you a status for each one.

javascript
1async function main() {
2  const results = await Promise.allSettled([
3    getUser(),
4    Promise.reject(new Error("orders failed")),
5    getSettings(),
6  ]);
7
8  console.log(results);
9}
10
11main().catch(console.error);

This is useful for dashboards, batch jobs, or cleanup routines where partial success is still valuable.

Different Promise Types Are Not a Problem

The promises can come from HTTP calls, filesystem reads, database queries, timers, or any mix of async functions. They do not need to be "the same kind" of promise. Promises are a common protocol for eventual completion, so grouping them is normal.

What does matter is dependency. If one operation needs the output of another, then they cannot run concurrently. In that case, sequence is the correct model and Promise.all is the wrong tool.

Handle Errors Intentionally

Promise.all rejects on the first failure, but the other operations may still be running in the background because JavaScript promises are not magically cancelled. If cancellation matters, you need explicit cancellation support such as AbortController in APIs that support it.

That distinction is important in network-heavy code. "Rejected early" is not the same as "all other work stopped."

Common Pitfalls

  • Awaiting each operation one by one when they could run concurrently.
  • Assuming the promises must all return the same data type.
  • Using Promise.all when partial failure handling requires Promise.allSettled.
  • Forgetting that a rejected Promise.all does not automatically cancel the other tasks.
  • Running dependent operations concurrently when they actually require sequencing.

Summary

  • Use Promise.all to wait for multiple independent promises concurrently.
  • The promises may come from different functions and resolve to different types.
  • Start the work first, then await the group if you want real concurrency.
  • Use Promise.allSettled when you need every result, including failures.
  • Choose concurrency only for independent operations, not dependent ones.

Course illustration
Course illustration

All Rights Reserved.