Back to stories
<Frontend/>

Async in JavaScript: Promise.all and allSettled, When to Use Each

Share by

Async in JavaScript: Promise.all and allSettled, When to Use Each

When you have several async operations (e.g. API calls), you can run them in parallel (all at once) or sequentially (one after another). Promise.all and Promise.allSettled are the main tools for parallel work. This post explains when to use each and how to handle errors.


Sequential: one after another

Running sequentially means you start the next operation only after the previous one finishes. You do it by awaiting in a loop or by chaining .then().

Use it when:

  • The next call depends on the result of the previous one (e.g. get user, then get their orders).
  • You must respect rate limits or order (e.g. process queue items in order).
  • You want to fail fast and not trigger more work after the first failure.

Example:

const results = []
for (const id of ids) {
  const data = await fetchItem(id)
  results.push(data)
}

Parallel: Promise.all

Promise.all takes an array of promises and returns a single promise that resolves when all of them resolve, with an array of results in the same order. If any promise rejects, Promise.all rejects immediately with that error; the others keep running in the background but their results are ignored.

Use it when:

  • The operations are independent and you want all results.
  • You want to fail fast: as soon as one fails, you get the error and can short-circuit.

Example:

const [user, posts, comments] = await Promise.all([
  fetchUser(id),
  fetchPosts(id),
  fetchComments(id),
])

Parallel: Promise.allSettled

Promise.allSettled runs all promises and always resolves (never rejects). The result is an array of objects: each has status: 'fulfilled' | 'rejected', and either value (if fulfilled) or reason (if rejected). You can then handle successes and failures per item.

Use it when:

  • You want to run all operations and handle each result or error individually (e.g. batch validation, multiple independent requests where one failure shouldn't cancel the rest).

Example:

const outcomes = await Promise.allSettled([
  fetchA(),
  fetchB(),
  fetchC(),
])
for (const outcome of outcomes) {
  if (outcome.status === 'fulfilled') use(outcome.value)
  else log(outcome.reason)
}

When to use which

GoalTool
All must succeed; fail fast on first errorPromise.all
Run all; handle each success/failure separatelyPromise.allSettled
One depends on the previousSequential (loop with await)

Summary

  • Sequential (await in loop): Use when order or dependencies matter, or when you want to stop on first failure.
  • Promise.all: Use for independent parallel work when you need all results and want to fail fast if any reject.
  • Promise.allSettled: Use for independent parallel work when you want every result or error and no single failure should cancel the rest. Choose the right pattern so async work is fast and errors are handled the way you expect.