creation

Promise.withResolvers

Creates a promise and exposes its resolve and reject callbacks alongside it, avoiding the need to capture them from a new Promise executor. Added in ES2024 for the 'deferred' pattern.

const { promise, resolve, reject } = Promise.withResolvers()

Parameters

Parameter Purpose
promise The new pending promise
resolve Function to fulfill the promise from outside its executor
reject Function to reject the promise from outside

Examples

const { promise, resolve, reject } = Promise.withResolvers();
document.getElementById('ok').onclick  = () => resolve('yes');
document.getElementById('no').onclick  = () => reject(new Error('declined'));
await promise;

Bridge event listeners to a single awaitable outcome without wrapping in new Promise.

function createQueue() {
  const items = [];
  const waiters = [];
  return {
    push(v) {
      if (waiters.length) waiters.shift().resolve(v);
      else items.push(v);
    },
    async pop() {
      if (items.length) return items.shift();
      const w = Promise.withResolvers();
      waiters.push(w);
      return w.promise;
    }
  };
}

Cleaner deferred pattern than storing resolve/reject in outer variables.

// Old pattern (pre-ES2024)
let resolve, reject;
const p = new Promise((res, rej) => { resolve = res; reject = rej; });

Promise.withResolvers replaces this boilerplate with one line.

Gotcha

ES2024 — check runtime support (Node 22+, modern Chrome/Firefox/Safari). Exposing resolve/reject widely creates the same 'multiple resolvers' risk as new Promise — first call wins, others ignored.

Related

← All JS Promise reference · async/await vs promises vs callbacks