The Promise
constructor is primarily used to wrap functions that do not already support promises.
The Promise
constructor is primarily used to wrap functions that do not already support promises.
executor
A function
to be executed by the constructor. It receives two functions as parameters: resolutionFunc
and rejectionFunc
. 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 resolutionFunc
or rejectionFunc
are invoked. Note that if you call resolutionFunc
or rejectionFunc
and pass another Promise
object as an argument, it 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.
readFile("./data.txt", (error, result) => { // This callback will be called when the task is done, with the // final `error` or `result`. Any operation dependent on the // result must be defined within this callback. }); // Code here is immediately executed after the `readFile` request // is fired. It does not wait for the callback to be called, hence // making `readFile` "asynchronous".
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:
function executor(resolutionFunc, rejectionFunc) { // Typically, some asynchronous operation that accepts a callback, // like the `readFile` function above }
resolutionFunc
and rejectionFunc
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.
resolutionFunc(value) // call on resolved rejectionFunc(reason) // call on rejected
The resolutionFunc
value
parameter can be another promise object, in which case the promise gets dynamically inserted into the promise chain. The rejectionFunc
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
.
About the executor
, it's important to understand the following:
executor
return value is ignored.executor
, the promise is rejected.So the mechanism by which the code within the executor
has effect is as follows:
Promise
object, it also generates a corresponding pair of functions for resolutionFunc
and rejectionFunc
; these are "tethered" to the Promise
object.executor
has the opportunity to perform some operation. The eventual completion of the asynchronous task is communicated with the promise instance via the side effect caused by resolutionFunc
or rejectionFunc
. The side effect is that the Promise
object either becomes "fulfilled", or "rejected".resolutionFunc
or rejectionFunc
affects the promise's state, and subsequent calls to either function can neither change the fulfillment value/rejection reason nor toggle the state from "fulfilled" to "rejected" or opposite.return
statements within the executor
merely impacts control flow and alters whether a part of the function is executed, but does not have any impact on the promise's fulfillment value.And so, given all the above, here's a summary of the typical flow:
executor
typically wraps some asynchronous operation which provides a callback-based API.executor
code, so it has access to the resolutionFunc
and rejectionFunc
.resolutionFunc
or rejectionFunc
.resolutionFunc
or rejectionFunc
is called, the promise's state moves from "pending" to either "fulfilled" or "rejected".Promise
object (asynchronously) invokes any further handlers associated by .then(handleFulfilled)
or .catch(handleRejected)
.resolutionFunc
or rejectionFunc
, i.e., the fulfillment value or rejection reason, is passed to the invocation of handleFulfilled
and handleRejected
as an input parameter (see Chained Promises).For example, the callback-based readFile
API above can be transformed into a promise-based one.
const readFilePromise = (path) => new Promise((resolve, reject) => { readFile(path, (error, result) => { if (error) { reject(error); } else { resolve(result); } }); }); readFilePromise("./data.txt") .then((result) => console.log(result)) .catch((error) => console.error("Failed to read data"));
A Promise
object is created using the new
keyword and its constructor. This constructor takes a function, called the "executor function", as its parameter. This function should take two functions as parameters. The first of these functions (resolve
) is called when the asynchronous task completes successfully and returns the results of the task as a value. The second (reject
) is called when the task fails, and returns the reason for failure, which is typically an error object.
const myFirstPromise = new Promise((resolve, reject) => { // do something asynchronous which eventually calls either: // // resolve(someValue) // fulfilled // or // reject("failure reason") // rejected });
To provide a function with promise functionality, have it return a promise:
function myAsyncFunction(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest() xhr.open("GET", url) xhr.onload = () => resolve(xhr.responseText) xhr.onerror = () => reject(xhr.statusText) xhr.send() }); }
Desktop | Mobile | Server | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | Deno | Node.js | |
Promise |
32 |
12 |
29
Constructor requires a new operator since version 37.
|
No |
19 |
8
Constructor requires a new operator since version 10.
|
4.4.3 |
32 |
29
Constructor requires a new operator since version 37.
|
19 |
8
Constructor requires a new operator since version 10.
|
2.0 |
1.0 |
0.12.0
Constructor requires a new operator since version 4.
|
© 2005–2022 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise