What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Promise.allSettled() does not throw just because one of its input promises rejects. Once every input has settled, it fulfills with an array of outcome objects. Check each object’s status: use value for fulfilled outcomes and reason for rejected ones, then decide what each failure means for your application.
Inspect each result by its status
A rejected input appears in the results as an object with status: "rejected" and a reason property. A fulfilled input has status: "fulfilled" and a value property. Branch before reading either field:
As an Amazon Associate I earn from qualifying purchases.
const results = await Promise.allSettled(tasks);
for (const [index, result] of results.entries()) {
if (result.status === "fulfilled") {
useValue(index, result.value);
} else {
reportFailure(index, result.reason);
}
}
The aggregate promise normally fulfills after all inputs settle, including when some inputs reject. That means the await itself is not where you handle those individual rejections; handle them in the returned array.
Separate successful outcomes from failures
If your application needs to keep successes while reporting failures, collect both explicitly:
#1 Best Overall
const results = await Promise.allSettled(requests);
const values = [];
const failures = [];
results.forEach((result, index) => {
if (result.status === "fulfilled") {
values.push({ index, value: result.value });
} else {
failures.push({ index, reason: result.reason });
}
});
if (failures.length > 0) {
console.error("Some requests failed", failures);
}
This example records failures; it does not decide whether they are harmless. Make that decision according to the task and product requirements rather than treating every rejection alike.
Keep outcomes associated with the right task
The returned array follows the order of the input promises, not the order in which they finish. Use that guarantee to associate results with labels or records:
Rank #2
const jobs = [
{ name: "profile", promise: loadProfile() },
{ name: "settings", promise: loadSettings() },
];
const outcomes = await Promise.allSettled(jobs.map((job) => job.promise));
const namedOutcomes = outcomes.map((outcome, index) => ({
name: jobs[index].name,
...outcome,
}));
For dynamically created work, keep the input records or pair each promise with an identifier. Do not match failures to tasks based on which request completed first.
Recommended Free Tools
Choose what a rejection means for your application
Promise.allSettled() reports each outcome; it does not supply a retry, logging, or recovery policy. Decide what should happen after inspecting the results:
Rank #3
- Independent optional work: Keep successful results and report or record failures. Continue only if partial success is acceptable for the feature.
- Transient failure: Retry only if repeating the operation is safe and your application’s retry rules permit it.
allSettled()does not retry automatically. - Required work: If any required operation fails, turn that outcome into an appropriate application-level error. A fulfilled aggregate promise does not prove every task succeeded.
- User-facing operation: Give users useful context without exposing sensitive raw error details.
Use Promise.all() when every task must succeed
Choose the combinator based on the relationship between the tasks and what counts as a useful result:
| Question | Promise.allSettled() |
Promise.all() |
|---|---|---|
| What does the caller need? | Every input’s outcome, including rejections. | A combined result when every input fulfills. |
| What happens if an input rejects? | The aggregate fulfills after all inputs settle; inspect the rejected entries. | The aggregate rejects when an input rejects. |
| When does it fit? | Independent tasks where partial success or a complete outcome report is useful. | Tasks whose combined operation is useful only when all inputs succeed. |
Promise.all() rejecting does not cancel the other work; inputs may continue executing. If cancellation is required, implement it separately rather than treating rejection as cancellation. For further detail, see MDN’s Promise.allSettled() reference and Promise.all() reference.
Rank #4
Format rejection reasons defensively
A rejected promise’s reason is the value used to reject it. It is often an Error, but JavaScript does not require that. Avoid assuming reason.message exists:
function describeReason(reason) {
if (reason instanceof Error) {
return reason.message;
}
return String(reason);
}
const results = await Promise.allSettled(tasks);
for (const result of results) {
if (result.status === "rejected") {
console.error("Task failed:", describeReason(result.reason));
}
}
Keep structured error handling appropriate to your application; converting a reason to text is useful for display or logging, but should not replace any domain-specific handling.
Best Value
Do not use global rejection events as normal control flow
Global unhandled-rejection events are intended as fallback or debugging mechanisms for rejections without a handler. They are not a substitute for inspecting expected outcomes at the operation that calls Promise.allSettled(). MDN’s promise rejection events guide describes those events and their role.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




