Що робить Promise.withResolvers()?
Що робить Promise.withResolvers()
Метод:
const { promise, resolve, reject } = Promise.withResolvers();створює новий проміс і одразу повертає об'єкт, у якому є три властивості:
| Властивість | Тип | Опис |
|---|---|---|
promise | Promise | Сам проміс, який можна повернути або чекати |
resolve | Function | Переводить проміс у стан fulfilled |
reject | Function | Переводить проміс у стан rejected |
Тобто це офіційний спосіб отримати зовнішні resolve/reject,
без потреби писати new Promise((resolve, reject) => { ... }).
Приклад
const { promise, resolve, reject } = Promise.withResolvers();
setTimeout(() => resolve('Успіх!'), 1000);
promise.then(console.log).catch(console.error);Через секунду:
Успіх!Все те саме, що раніше доводилося робити "вручну" через new Promise.
Те саме "по-старому"
До появи Promise.withResolvers() писали так:
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});Це виглядало неочевидно (особливо для TypeScript)
і було потенційно небезпечно - resolve і reject можна було перевизначити.
Тепер це можна зробити безпечно і декларативно:
const { promise, resolve, reject } = Promise.withResolvers();Приклад 2 - використання для "зовнішнього керування"
Це зручно, коли потрібно керувати завершенням проміса ззовні, наприклад:
function waitForEvent(emitter, event) {
const { promise, resolve } = Promise.withResolvers();
emitter.once(event, resolve);
return promise;
}Тепер можна писати:
await waitForEvent(button, 'click');
console.log('Кнопку натиснуто!');Приклад 3 - відкладені задачі (Deferred)
Можна створити відкладений проміс (deferred pattern):
const deferred = Promise.withResolvers();
// десь у коді
setTimeout(() => deferred.resolve('Готово!'), 2000);
// а в іншому місці
deferred.promise.then(console.log);Вивід через 2 секунди:
Готово!Приклад 4 - комбінування з AbortController
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);Виведе:
Error: СкасованоСтруктура, що повертається
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 - скоро |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.