Promise.withResolvers S4
- Stage: Stage 4
- Status: Finished
- ECMAScript edition: ES2024
- Synchronized: Aug 28, 2026
- 中文译文 · Source repository
The proposal addresses boilerplate code required to extract resolve and reject functions when creating a Promise manually. It adds a static method Promise.withResolvers() that returns an object containing the promise and its resolve/reject functions.
The README below comes from the upstream repository and may contain outdated stage or status metadata. Use the proposal details above as the current source of truth.
Promise.withResolvers
Note: this proposal is now at stage 4. See the spec PR here: https://github.com/tc39/ecma262/pull/3179
Status
Stage: 4
Champions:
- Peter Klecha (@peetklecha)
Authors:
- Peter Klecha (@peetklecha)
Stage 3 slides Stage 2 slides Stage 1 slides
Synopsis
When hand-rolling a Promise, the user must pass an executor callback which takes two arguments: a resolve function, which triggers resolution of the promise, and a reject function, which triggers rejection. This works well if the callback can embed a call to an asynchronous function which will eventually trigger the resolution or rejection, e.g., the registration of an event listener.
Often however developers would like to configure the promise's resolution and rejection behavior after instantiating it. Today this requires a cumbersome workaround to extract the resolve and reject functions from the callback scope:
Developers may also have requirements that necessitate passing resolve/reject to more than one caller, so they MUST implement it this way:
This is boilerplate code that is very frequently re-written by developers. This proposal simply seeks to add a static method, tentatively called withResolvers, to the Promise constructor which returns a promise along with its resolution and rejection functions conveniently exposed.
This method or something like it may be known to some committee members under the name defer or deferred, names also sometimes applied to utility functions in the ecosystem. This proposal adopts a more descriptive name for the benefit of users who may not be familiar with those historical functions.
Existing implementations
Libraries and applications continually re-invent this wheel. Below are just a handful of examples.