JavaScript Create Promise

In general, there are 3 ways to create a new promise in JavaScript:

Using the Promise Constructor

The Promise constructor takes a single parameter, an executor function. When you call new Promise(executor) , JavaScript immediately executes your executor function with 2 arguments: resolve() and reject() .

function executor ( resolve, reject ) { typeof resolve; typeof reject; } new Promise (executor);

The executor() function is then responsible for calling resolve() to mark the promise as fulfilled (successful) or rejected (failed).

const success = new Promise ( function executor ( resolve ) { resolve( 'OK' ); }); const fail = new Promise ( function executor ( resolve, reject ) { reject( new Error ( 'Oops' )); }); const str = await success; str; const err = await fail.catch( err => err); err.message;

Using Static Helpers

The Promise.resolve() function lets you create a new promise that is immediately fulfilled.

const p = Promise .resolve( 42 ); p.then( v => { v; });

You can think of Promise.resolve(v) as short for new Promise(resolve => resolve(v)) .

Similarly, the Promise.reject() function lets you create a new promise that is immediately rejected.

const p = Promise .reject( new Error ( 'Oops!' )); p.catch( err => { err.message; });

Be careful with Promise.reject() : if you don't immediately add a .catch() handler to your new promise, you'll get an unhandled promise rejection.

then() and catch()

When you call .then() or .catch() , JavaScript creates a new promise.

const p = Promise .resolve( 'Hello' ); const p2 = p.then( str => ` ${str} World` ); p2 instanceof Promise ; p2 === p;

Without Executing

JavaScript promises are "hot" in the sense that JavaScript executes the executor function immediately.

If you find yourself wanting a "cold" promise in the sense that your promise doesn't execute until you await on it, you should just use an async function. Calling an async function returns a new promise every time.

async function getAnswer ( ) { return 42 ; } const p1 = getAnswer(); p1 instanceof Promise ; const p2 = getAnswer(); p2 instanceof Promise ; p2 === p1;

Another common alternative is the deferred pattern, where you create a promise that has resolve() and reject() functions that you can call outside the executor() function.

Promise .deferred = function ( ) { let resolve = null ; let reject = null ; const p = new Promise ( ( _resolve, _reject ) => { resolve = _resolve; reject = _reject; }); return Object .assign(p, { resolve, reject }); }; const p = Promise .deferred(); p.then( v => { v; }); p.resolve( 42 );

However, the deferred pattern is considered an antipattern. That's because synchronous errors that occur outside the executor function won't reject the promise!

const p1 = new Promise ( () => { throw new Error ( 'Oops!' ); }); p1.catch( err => { err.message; }); const p2 = Promise .deferred(); throw new Error ( 'Oops!' );

More Fundamentals Tutorials