JavaScript Promise Methods Reference
All Promise static and instance methods — syntax, parameters, edge cases, and a live code runner
| Method | Resolves when | Rejects when | ES |
|---|---|---|---|
| Promise.all() | All fulfill | Any rejects (fail-fast) | ES2015 |
| Promise.allSettled() | All settle | Never | ES2020 |
| Promise.any() | Any fulfills (first) | All reject → AggregateError | ES2021 |
| Promise.race() | First to settle | First to reject | ES2015 |
| Promise.resolve() | Immediately | Never (unless thenable rejects) | ES2015 |
| Promise.reject() | Never | Immediately | ES2015 |
| Promise.withResolvers() | When resolve() called | When reject() called | ES2024 |
| Promise.try() | fn returns / resolves | fn throws / rejects | ES2025 |
Promise.all()Static MethodES2015Promise.all(iterable)Takes an iterable of Promises and returns a new Promise that fulfills when ALL input Promises fulfill, with an array of their values in the same order. If ANY input Promise rejects, the returned Promise immediately rejects with that rejection reason — a fail-fast strategy.
Promise.allSettled()Static MethodES2020Promise.allSettled(iterable)Returns a Promise that fulfills after ALL input Promises have settled (either fulfilled or rejected). Each element of the resulting array is a settlement descriptor: `{ status: 'fulfilled', value }` or `{ status: 'rejected', reason }`. Never rejects — always waits for everything to complete.
Promise.any()Static MethodES2021Promise.any(iterable)Returns a Promise that fulfills as soon as ANY input Promise fulfills, with that Promise's value. Rejects only if ALL input Promises reject — with an `AggregateError` containing all rejection reasons. It is the logical opposite of `Promise.all()`.
Promise.race()Static MethodES2015Promise.race(iterable)Returns a Promise that settles (fulfills or rejects) as soon as the FIRST input Promise settles — mirroring its state and value. Unlike `Promise.any()`, a rejection from the first-to-settle Promise also rejects the race. It is useful for adding timeouts to async operations.
Promise.resolve()Static MethodES2015Promise.resolve(value?)Returns a Promise object that is resolved (fulfilled) with a given value. If the value is a thenable (has a `.then` method), the returned Promise adopts the thenable's state. If the value is already a Promise created by the same constructor, it is returned as-is.
Promise.reject()Static MethodES2015Promise.reject(reason?)Returns a Promise object that is rejected with a given reason. Unlike `Promise.resolve()`, the reason is never unwrapped — even if it is a Promise or thenable, it becomes the rejection reason directly. Always attach a `.catch()` handler to avoid unhandled rejection warnings.
Promise.withResolvers()Static MethodES2024Promise.withResolvers()Returns an object containing a new Promise along with its `resolve` and `reject` functions. This avoids the boilerplate of declaring `let resolve, reject` variables outside a `new Promise()` constructor and makes the deferred pattern idiomatic.
Promise.try()Static MethodES2025Promise.try(fn, ...args)Calls `fn(...args)` and wraps the result in a Promise. If `fn` throws synchronously or returns a rejected Promise, the returned Promise rejects. If `fn` returns a value or fulfilled Promise, the returned Promise fulfills. Eliminates the need for a `try/catch` wrapper around mixed sync/async functions.
You have three API calls that must all succeed before rendering a page. You use Promise.all() — but one fails and you lose the results of the other two. You switch to Promise.allSettled() to get all results regardless of failures. But now you need the first successful result from three CDN mirrors, ignoring failures — that’s Promise.any(), not Promise.race() (which resolves on the first settled, including rejections). Four static methods that look similar but behave very differently.
Why This Reference (Not the Promise Visualizer)
PureDevTools has a Promise Visualizer that shows Promise chains as interactive timelines — great for understanding execution order. This reference covers all Promise static methods (all, allSettled, any, race, resolve, reject, withResolvers, try) and instance methods (.then, .catch, .finally) with edge cases and interactive examples.
What Are JavaScript Promises?
A Promise is an object representing the eventual completion or failure of an asynchronous operation. It has three states:
- Pending: initial state — not fulfilled or rejected
- Fulfilled: the operation completed successfully, producing a value
- Rejected: the operation failed, producing a rejection reason (typically an
Error)
Once a Promise is fulfilled or rejected it is settled — its state is immutable. All handlers attached via .then(), .catch(), or .finally() receive the settled value and are invoked as microtasks.
const p = new Promise((resolve, reject) => {
// async operation
setTimeout(() => resolve("done!"), 100);
});
p.then(value => console.log(value)); // "done!" (after 100ms)
Static Methods
Promise.all() — Fail-Fast Parallel Execution
Promise.all() waits for every Promise in the iterable to fulfill. If any rejects, the whole result rejects immediately with that reason.
async function fetchUser(id) {
return { id, name: "User " + id };
}
// Run three requests in parallel — wait for all
const [u1, u2, u3] = await Promise.all([
fetchUser(1),
fetchUser(2),
fetchUser(3),
]);
console.log(u1.name, u2.name, u3.name); // User 1 User 2 User 3
When to use: When all results are required and a single failure should abort the operation — for example, fetching all resources needed to render a page.
Promise.allSettled() — Wait for Everything
Unlike Promise.all(), allSettled() never rejects. It waits for every Promise to settle and returns an array of { status, value | reason } descriptors.
const results = await Promise.allSettled([
fetch("/api/user"),
fetch("/api/posts"),
fetch("/api/comments"), // might fail
]);
for (const result of results) {
if (result.status === "fulfilled") {
console.log("success:", result.value.url);
} else {
console.error("failed:", result.reason.message);
}
}
When to use: Independent parallel operations where partial success is acceptable — sending analytics events, pre-loading optional resources.
Promise.any() — First Success Wins
Promise.any() returns the value of the first Promise that fulfills. Rejects only when ALL input Promises reject, throwing an AggregateError containing all reasons.
// Try multiple CDN endpoints — use whichever responds first
const image = await Promise.any([
fetch("https://cdn1.example.com/logo.png"),
fetch("https://cdn2.example.com/logo.png"),
fetch("https://cdn3.example.com/logo.png"),
]);
console.log("loaded from:", image.url);
When to use: Redundant resource fetching, failover strategies, or any “first available” pattern where rejections are expected and normal.
Promise.race() — First to Settle Wins
Promise.race() resolves or rejects as soon as the first Promise in the iterable settles — with its value or reason.
// Timeout pattern
function withTimeout(promise, ms) {
const timeout = new Promise((_, reject) =>
setTimeout(() => reject(new Error(`Timed out after ${ms}ms`)), ms)
);
return Promise.race([promise, timeout]);
}
try {
const data = await withTimeout(fetch("/api/slow-endpoint"), 3000);
console.log("got data:", data.status);
} catch (err) {
console.error(err.message); // Timed out after 3000ms
}
When to use: Timeout enforcement, or when the first response (fulfilled or rejected) determines the outcome.
Promise.resolve() and Promise.reject() — Creating Settled Promises
These factory methods create immediately-settled Promises — useful for normalising values and early returns.
// Normalise any value to a Promise
async function getConfig(source) {
if (typeof source === "object") {
return Promise.resolve(source); // already an object — wrap it
}
return fetch(source).then(r => r.json()); // URL — fetch it
}
// Early rejection in a validation chain
async function processAge(age) {
if (typeof age !== "number") return Promise.reject(new TypeError("age must be a number"));
if (age < 0) return Promise.reject(new RangeError("age cannot be negative"));
return age;
}
Promise.withResolvers() — Deferred Pattern
Promise.withResolvers() (ES2024) returns { promise, resolve, reject } — a Promise together with its resolution controls, making the deferred pattern idiomatic.
// Wrap a callback-based API cleanly
function readFile(path) {
const { promise, resolve, reject } = Promise.withResolvers();
fs.readFile(path, "utf8", (err, data) => {
if (err) reject(err);
else resolve(data);
});
return promise;
}
// Signal-based coordination
function waitForCondition(emitter, event) {
const { promise, resolve, reject } = Promise.withResolvers();
emitter.once(event, resolve);
emitter.once("error", reject);
return promise;
}
Promise.try() — Uniform Sync/Async Error Handling
Promise.try() (ES2025) calls a function and always returns a Promise, converting synchronous throws into rejections.
// Before Promise.try() — synchronous errors escape the chain
async function riskyOp() {
const data = JSON.parse(rawInput); // might throw synchronously!
return processData(data);
}
// If JSON.parse throws, the error escapes the Promise chain
// With Promise.try() — all errors become rejections
const result = await Promise.try(() => {
const data = JSON.parse(rawInput); // sync throw → rejection
return processData(data);
});
Instance Methods
.then() — Chaining Transformations
.then() is the core method for consuming a Promise’s value and chaining further operations. It returns a new Promise whose value is the return value of the handler.
fetch("/api/user")
.then(response => response.json()) // parse JSON
.then(user => user.name.toUpperCase()) // transform
.then(name => console.log("Hello,", name)) // consume
.catch(err => console.error(err)); // catch any error
The key rule: return a value to fulfill the next step, return a Promise to chain into it (flat, not nested), throw to reject the next step.
// Returning a Promise in .then() flattens the chain
Promise.resolve("https://api.example.com/data")
.then(url => fetch(url)) // returns Promise<Response>
.then(res => res.json()) // flat — not Promise<Promise<...>>
.then(data => console.log(data));
.catch() — Handling Rejections
.catch() is shorthand for .then(undefined, onRejected). A catch handler can recover from a rejection by returning a value:
async function loadUser(id) {
return fetch(`/api/users/${id}`)
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(err => {
console.error("Load failed:", err.message);
return { id, name: "Anonymous", fallback: true }; // default user
});
}
.catch() placed at the end of a chain catches any rejection from any preceding step — it is a single catch for the entire chain.
.finally() — Guaranteed Cleanup
.finally() runs its handler regardless of whether the Promise fulfills or rejects. The original value passes through unchanged — making it safe for cleanup code that should not alter the result.
async function submitForm(data) {
setLoading(true);
return fetch("/api/submit", { method: "POST", body: JSON.stringify(data) })
.then(res => res.json())
.catch(err => {
reportError(err);
throw err; // re-throw to keep it rejected
})
.finally(() => {
setLoading(false); // always runs, value/rejection passes through
});
}
Promise Combinators at a Glance
| Method | Resolves when | Rejects when | Result type |
|---|---|---|---|
Promise.all() | All fulfill | Any rejects (first reason) | T[] in input order |
Promise.allSettled() | All settle | Never | SettledResult[] |
Promise.any() | Any fulfills (first value) | All reject | T |
Promise.race() | First to settle (either) | First to reject | T |
Common Pitfalls
Forgotten Return
Always return inside .then() handlers. Without return, the next handler receives undefined:
// Bug — missing return
Promise.resolve([1, 2, 3])
.then(arr => {
arr.map(n => n * 2); // ← no return!
})
.then(result => console.log(result)); // undefined
// Fix
Promise.resolve([1, 2, 3])
.then(arr => arr.map(n => n * 2)) // ← return
.then(result => console.log(result)); // [2, 4, 6]
Nested Promises (Promise Hell)
Returning a Promise from .then() flattens the chain. Calling .then() inside .then() creates nested Promises — the async equivalent of callback hell:
// Avoid — nested
promise.then(v => otherPromise.then(v2 => console.log(v, v2)));
// Prefer — flat chain
promise
.then(v => otherPromise.then(v2 => [v, v2]))
.then(([v, v2]) => console.log(v, v2));
Unhandled Rejections
Every Promise chain must have a .catch(). Unhandled rejections cause warnings in browsers and can crash Node.js:
// Bad — no catch
fetch("/api/data").then(r => r.json()); // unhandled rejection if fetch fails
// Good
fetch("/api/data")
.then(r => r.json())
.catch(err => console.error("fetch failed:", err));
Frequently Asked Questions
What is the difference between Promise.all() and Promise.allSettled()?
Promise.all() is fail-fast: the first rejection causes the entire operation to reject immediately, and results from other Promises are discarded. Promise.allSettled() always waits for every Promise to settle and returns a result for each one — fulfilled or rejected. Use all() when all results are required and one failure should abort. Use allSettled() when you need all results regardless of individual failures.
When should I use Promise.any() vs Promise.race()?
Use Promise.any() when you want the first successful result and rejections should be ignored until all have failed. Use Promise.race() when you want the first settled result (fulfilled or rejected) — for example, implementing timeouts where a rejection from the timeout branch should cancel the operation.
Can I cancel a Promise?
Native Promises cannot be cancelled. Once created, a Promise runs to completion. The standard approach for cancellation is the AbortController API: pass signal to fetch() and call controller.abort() to cancel. For custom async operations, check the signal’s aborted property or listen to its abort event.
What is the difference between .then(fn1, fn2) and .then(fn1).catch(fn2)?
With .then(fn1, fn2), fn2 only catches rejections from the original Promise — not errors thrown by fn1. With .then(fn1).catch(fn2), fn2 catches both the original rejection AND any error thrown inside fn1. The chained .catch() form is almost always preferred because it provides broader error coverage.
Why do Promise handlers always run asynchronously?
Even if a Promise is already settled, .then() handlers are scheduled as microtasks and run asynchronously — never synchronously inline. This ensures consistent behaviour regardless of when the Promise settled. It prevents subtle ordering bugs where code after .then() would behave differently depending on whether the Promise had already resolved.
What is Promise.withResolvers() and when should I use it?
Promise.withResolvers() (ES2024) returns { promise, resolve, reject } — the Promise’s resolution controls are exposed outside the constructor. Before this method, wrapping callback-based APIs required declaring let resolve, reject variables in the outer scope before the new Promise() constructor. withResolvers() makes this pattern concise and is ideal for wrapping event-based or callback-based APIs, implementing deferred objects, and inter-component signalling.