Get to know MDN better
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The Promise() constructor creates Promise objects. It is primarily used to wrap callback-based APIs that do not already support promises.
Note: Promise() can only be constructed with new. Attempting to call it without new throws a TypeError.
A function to be executed by the constructor. It receives two functions as parameters: resolveFunc and rejectFunc. Any errors thrown in the executor will cause the promise to be rejected, and the return value will be neglected. The semantics of executor are detailed below.
When called via new, the Promise constructor returns a promise object. The promise object will become resolved when either of the functions resolveFunc or rejectFunc are invoked. Note that if you call resolveFunc and pass another promise object as an argument, the initial promise can be said to be "resolved", but still not "settled". See the Promise description for more explanation.
Traditionally (before promises), asynchronous tasks were designed as callbacks.
To take advantage of the readability improvement and language features offered by promises, the Promise() constructor allows one to transform the callback-based API to a promise-based one.
Note: If your task is already promise-based, you likely do not need the Promise() constructor.
The executor is custom code that ties an outcome in a callback to a promise. You, the programmer, write the executor. Its signature is expected to be:
resolveFunc and rejectFunc are also functions, and you can give them whatever actual names you want. Their signatures are simple: they accept a single parameter of any type.
The value parameter passed to resolveFunc can be another promise object, in which case the newly constructed promise's state will be "locked in" to the promise passed (as part of the resolution promise). The rejectFunc has semantics close to the throw statement, so reason is typically an Error instance. If either value or reason is omitted, the promise is fulfilled/rejected with undefined.
The executor's completion state has limited effect on the promise's state:
Note: The existence of pending promises does not prevent the program from exiting. If the event loop is empty, the program exits despite any pending promises (because those are necessarily forever-pending).
Here's a summary of the typical flow:
For example, the callback-based readFile API above can be transformed into a promise-based one.
The resolve and reject callbacks are only available within the scope of the executor function, which means you can't access them after the promise is constructed. If you want to construct the promise before deciding how to resolve it, you can use the Promise.withResolvers() method instead, which exposes the resolve and reject functions.
The resolve function has the following behaviors:
In the last case, it means code like:
Is roughly equivalent to:
Except that in the resolve(thenable) case:
Because resolve is called again with whatever thenable.then() passes to it as value, the resolver function is able to flatten nested thenables, where a thenable calls its onFulfilled handler with another thenable. The effect is that the fulfillment handler of a real promise will never receive a thenable as its fulfillment value.
To provide a function with promise functionality, have it return a promise by calling the resolve and reject functions at the correct times.
Calling resolveFunc causes the promise to become resolved, so that calling resolveFunc or rejectFunc again has no effect. However, the promise may be in any of the states: pending, fulfilled, or rejected.
This pendingResolved promise is resolved the time it's created, because it has already been "locked in" to match the eventual state of the inner promise, and calling resolveOuter or rejectOuter or throwing an error later in the executor has no effect on its eventual state. However, the inner promise is still pending until 100ms later, so the outer promise is also pending:
This fulfilledResolved promise becomes fulfilled the moment it's resolved, because it's resolved with a non-thenable value. However, when it's created, it's unresolved, because neither resolve nor reject has been called yet. An unresolved promise is necessarily pending:
Calling rejectFunc obviously causes the promise to reject. However, there are also two ways to cause the promise to instantly become rejected even when the resolveFunc callback is called.
| ECMAScript® 2027 Language Specification # sec-promise-constructor |
Enable JavaScript to view this browser compatibility table.
This page was last modified on Jul 10, 2025 by MDN contributors.
Your blueprint for a better internet.
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998–2026 by individual mozilla.org contributors. Content available under a Creative Commons license.