Promise
The Promise global object represents the eventual result of an asynchronous operation, and its static methods create, combine, and race promises. Each instance is a promise that starts out pending and settles once, either fulfilled with a value or rejected with a reason:
> const ready = Promise.resolve(42);
undefined
> ready
Promise { 42 }
> await ready
42
Promise is an ECMAScript built-in, added in ES2015. The async and await keywords build on it: an async function always returns a promise, and await pauses until one settles.
Syntax
The Promise constructor takes an executor function:
new Promise(<executor>)
| Parameter | Description |
|---|---|
executor |
A required function that receives resolve and reject functions and runs synchronously during construction |
The constructor returns a new promise that settles when the executor calls resolve or reject. It requires new, and calling Promise() without it throws a TypeError. A throw inside the executor rejects the promise, unless resolve or reject was already called.
Key Static Methods and Properties
| Member | Kind | Description |
|---|---|---|
Promise.resolve() |
Static method | Returns a promise fulfilled with the given value, or the value itself when it’s a promise whose .constructor is Promise |
Promise.reject() |
Static method | Returns a promise rejected with the given reason |
Promise.all() |
Static method | Fulfills with an array of all results, or rejects as soon as one input rejects |
Promise.allSettled() |
Static method | Fulfills with an array of { status, value } or { status, reason } objects once every input settles |
Promise.any() |
Static method | Fulfills with the first fulfilled value, or rejects with an AggregateError when all inputs reject (ES2021) |
Promise.race() |
Static method | Settles the same way as the first input to settle |
Promise.withResolvers() |
Static method | Returns an object with a new promise and its resolve and reject functions (ES2024) |
Promise.try() |
Static method | Calls a function and wraps its return value or thrown error in a promise (ES2025) |
Key Instance Methods and Properties
| Member | Kind | Description |
|---|---|---|
.then() |
Instance method | Registers fulfillment and rejection handlers and returns a new promise |
.catch() |
Instance method | Registers a rejection handler and returns a new promise |
.finally() |
Instance method | Registers a handler that runs on either outcome and passes the original result through |
Promise.withResolvers() is Baseline Widely available since 2026. Promise.try() is Baseline Newly available since 2025.
Examples
Handlers always run as microtasks, after the current synchronous code finishes, even when the promise is already fulfilled:
microtask-order.mjs
Promise.resolve("handler").then((message) => console.log(message));
console.log("sync code");
Running the file prints the synchronous line first:
$ node microtask-order.mjs
sync code
handler
Each call to .then() returns a new promise, so a chain passes values from one step to the next:
> await Promise.resolve(2).then((n) => n * 10).then((n) => n + 1)
21
The combinators differ in how they treat a rejection:
> const tasks = [Promise.resolve("a"), Promise.reject(new Error("b"))];
undefined
> (await Promise.allSettled(tasks)).map((result) => result.status)
[ 'fulfilled', 'rejected' ]
> await Promise.any(tasks)
'a'
> await Promise.all(tasks).catch((error) => error.message)
'b'
Promise.try() turns a synchronous throw into a rejection, so one .catch() handles both kinds of failure:
> await Promise.try(() => JSON.parse("{")).catch((error) => error.name)
'SyntaxError'
Promise.withResolvers() exposes resolve outside an executor, which suits promises settled by an event or callback:
with-resolvers.mjs
const { promise, resolve } = Promise.withResolvers();
setTimeout(() => resolve("done"), 10);
console.log(await promise);
The timer callback settles the promise, and the awaited value prints:
$ node with-resolvers.mjs
done
Common Gotchas
A handler that doesn’t return its inner promise lets the chain move on before that work finishes:
missing-return.mjs
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const steps = [];
await Promise.resolve()
.then(() => {
delay(10).then(() => steps.push("inner"));
})
.then(() => steps.push("outer"));
console.log(steps);
The log runs before the inner timer fires:
$ node missing-return.mjs
[ 'outer' ]
Returning delay(10).then(...) from the first handler makes the chain wait, and steps becomes [ 'inner', 'outer' ].
A rejected promise with no handler is an unhandled rejection. Browsers report an unhandledrejection event, and some server runtimes treat it as an uncaught error and exit the process by default.
Have a question about this? Mentor AI can show you examples, compare related terms, and point you to tutorials.
By Leodanis Pozo Ramos • Updated Nov. 4, 2026