Resolve a Promise in JavaScript
The Promise.resolve()
function is the most concise way to
create a fulfilled promise that contains the given value. For example,
suppose you wanted to create a promise that is fulfilled with the string 'Hello, World':
const p = Promise.resolve('Hello, World');
const str = await p;
str; // 'Hello, World'
return p.then(str => {
str; // 'Hello, World'
});
Resolved is Not the Same as Fulfilled
Explaining the difference between a promise that is resolved and a promise that is fulfilled is a common JavaScript interview question. The difference is subtle, but important.
The key difference is what happens when a promise is resolved with
another promise. When you call Promise.resolve(p)
, where p
is a
promise, you create a new promise that is tied to p
. If p
is
fulfilled, the returned promise is fulfilled with the same value.
If p
is rejected, the returned promise is rejected with the same value.
The Promises/A+ spec calls this process "assimilation".
const p = Promise.resolve('Hello, World');
const p2 = Promise.resolve(p);
const str = await p2;
// `p2` "assimilates" the value of `p`.
str; // 'Hello, World'
A promise that is resolved to another promise is still pending. In particular, a promise that is resolved can still become rejected!
async function fail() {
await new Promise(resolve => setTimeout(resolve, 100));
throw new Error('Oops');
}
// Calling `fail()` returns a promise that rejects after
// 100ms. So `p` will reject, even though it was resolved!
const p = Promise.resolve(fail());
const err = await p.catch(err => err);
err.message; // 'Oops'
Resolved is not a promise state. On the other hand, fulfilled is
one of 3 states a promise can be in, and once a promise transitions
to fulfilled, JavaScript executes any onFulfilled
callbacks you passed to the then()
function.
With the Promise Constructor
When you create a promise using new
, you call the Promise constructor.
The Promise constructor takes a single parameter, an executor
function.
The Promise constructor then executes the executor
function with 2
arguments: resolve()
and reject()
.
function executor(resolve, reject) {
typeof resolve; // 'function'
typeof reject; // 'function'
}
new Promise(executor);
Note that the first parameter is typically called resolve()
, not fulfill
.
That's because the resolve()
function in the promise constructor behaves
much like Promise.resolve()
. When you call resolve()
with a promise,
you "assimilate" the value of that promise.
const p = Promise.resolve('Hello, World');
const p2 = new Promise(resolve => resolve(p));
const str = await p2;
// `p2` "assimilates" the value of `p`.
str; // 'Hello, World'