Resolve a Promise in JavaScript

Jan 22, 2020

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'

More Fundamentals Tutorials