What does Promise.withResolvers() do?
What Promise.withResolvers() does
The method:
const { promise, resolve, reject } = Promise.withResolvers();creates a new promise and immediately returns an object that has three properties:
| Property | Type | Description |
|---|---|---|
promise | Promise | The promise itself, which can be returned or awaited |
resolve | Function | Moves the promise to the fulfilled state |
reject | Function | Moves the promise to the rejected state |
In other words, this is the official way to get external resolve/reject,
without needing to write new Promise((resolve, reject) => { ... }).
Example
const { promise, resolve, reject } = Promise.withResolvers();
setTimeout(() => resolve('Success!'), 1000);
promise.then(console.log).catch(console.error);After a second:
Success!Everything that previously had to be done "manually" via new Promise.
The same thing "the old way"
Before Promise.withResolvers() existed, this was written like this:
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});This looked non-obvious (especially for TypeScript)
and was potentially unsafe - resolve and reject could be overwritten.
Now it can be done safely and declaratively:
const { promise, resolve, reject } = Promise.withResolvers();Example 2 - using it for "external control"
This is handy when you need to control the completion of a promise from outside, for example:
function waitForEvent(emitter, event) {
const { promise, resolve } = Promise.withResolvers();
emitter.once(event, resolve);
return promise;
}Now you can write:
await waitForEvent(button, 'click');
console.log('Button clicked!');Example 3 - deferred tasks (Deferred)
You can create a deferred promise (the deferred pattern):
const deferred = Promise.withResolvers();
// somewhere in the code
setTimeout(() => deferred.resolve('Done!'), 2000);
// and elsewhere
deferred.promise.then(console.log);Output after 2 seconds:
Done!Example 4 - combining with AbortController
const controller = new AbortController();
const { promise, resolve, reject } = Promise.withResolvers();
controller.signal.addEventListener('abort', () => reject(new Error('Cancelled')));
setTimeout(() => resolve('Successful!'), 2000);
// somewhere later
controller.abort();
promise.catch(console.error);Outputs:
Error: CancelledThe returned structure
Promise.withResolvers<T>() =>
{ promise: Promise<T>, resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void }In TypeScript this makes the code safer - the IDE knows the type of
promiseand the type of itsresolve.
Features and behavior
| Feature | Description |
|---|---|
Creates a new Promise | without needing to manually write the constructor |
| Handy for "deferred" patterns | for example, when the result becomes known later |
Does not invoke an executor | no (resolve, reject) arguments - just an object |
| Allows external control | the promise can be controlled after it is created |
A simple analogy
Promise.withResolvers()is as if you created a promise with a remote control included.Previously you had to manually pull out the "resolve/reject" buttons, now they come right out of the box.
SUMMARY
| Property | What it does |
|---|---|
Promise.withResolvers() | Creates a promise + returns resolve and reject |
| Returns | { promise, resolve, reject } |
| Advantages | Cleaner, safer, and more type-safe than new Promise(...) |
| Used for | Deferred tasks, events, external control of a promise |
| Support | Chrome 120+, Node.js 20.11+, Deno 1.41+, Safari - coming soon |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.