Skip to main content

Що робить Promise.withResolvers()?

Що робить Promise.withResolvers()

Метод:

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

створює новий проміс і одразу повертає об'єкт, у якому є три властивості:

ВластивістьТипОпис
promisePromiseСам проміс, який можна повернути або чекати
resolveFunctionПереводить проміс у стан fulfilled
rejectFunctionПереводить проміс у стан rejected

Тобто це офіційний спосіб отримати зовнішні resolve/reject, без потреби писати new Promise((resolve, reject) => { ... }).


Приклад

javascript
const { promise, resolve, reject } = Promise.withResolvers(); setTimeout(() => resolve('Успіх!'), 1000); promise.then(console.log).catch(console.error);

Через секунду:

javascript
Успіх!

Все те саме, що раніше доводилося робити "вручну" через new Promise.


Те саме "по-старому"

До появи Promise.withResolvers() писали так:

javascript
let resolve, reject; const promise = new Promise((res, rej) => { resolve = res; reject = rej; });

Це виглядало неочевидно (особливо для TypeScript) і було потенційно небезпечно - resolve і reject можна було перевизначити.

Тепер це можна зробити безпечно і декларативно:

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

Приклад 2 - використання для "зовнішнього керування"

Це зручно, коли потрібно керувати завершенням проміса ззовні, наприклад:

javascript
function waitForEvent(emitter, event) { const { promise, resolve } = Promise.withResolvers(); emitter.once(event, resolve); return promise; }

Тепер можна писати:

javascript
await waitForEvent(button, 'click'); console.log('Кнопку натиснуто!');

Приклад 3 - відкладені задачі (Deferred)

Можна створити відкладений проміс (deferred pattern):

javascript
const deferred = Promise.withResolvers(); // десь у коді setTimeout(() => deferred.resolve('Готово!'), 2000); // а в іншому місці deferred.promise.then(console.log);

Вивід через 2 секунди:

javascript
Готово!

Приклад 4 - комбінування з AbortController

javascript
const controller = new AbortController(); const { promise, resolve, reject } = Promise.withResolvers(); controller.signal.addEventListener('abort', () => reject(new Error('Скасовано'))); setTimeout(() => resolve('Успішно!'), 2000); // десь пізніше controller.abort(); promise.catch(console.error);

Виведе:

javascript
Error: Скасовано

Структура, що повертається

javascript
Promise.withResolvers<T>() => { promise: Promise<T>, resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void }

У TypeScript це робить код безпечнішим - IDE знає тип promise і тип його resolve.


Особливості та поведінка

ОсобливістьОпис
Створює новий Promiseбез потреби вручну писати конструктор
Зручно для "deferred" патернівнаприклад, коли результат стане відомий пізніше
Не викликає executorжодних аргументів (resolve, reject) - тільки об'єкт
Дозволяє керувати ззовніпромісом можна керувати після його створення

Проста аналогія

Promise.withResolvers() - це наче ти створив проміс з пультом керування в комплекті.

Раніше доводилося вручну діставати кнопки "resolve/reject", тепер вони йдуть одразу з коробки.


ПІДСУМОК

ВластивістьЩо робить
Promise.withResolvers()Створює проміс + повертає resolve і reject
Повертає{ promise, resolve, reject }
ПеревагиЧистіше, безпечніше і типобезпечніше, ніж new Promise(...)
Використовується дляВідкладених задач, подій, зовнішнього керування промісом
ПідтримкаChrome 120+, Node.js 20.11+, Deno 1.41+, Safari - скоро

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.