Новий метод Promise.withResolvers тепер доступний у браузерах
Недавно у JavaScript додали новий статичний метод withResolvers() до класу Promise. Він повертає об’єкт, в якому міститься новий об’єкт promise і дві функції resolve
і reject
, за допомогою яких можна змінити стан проміса відповідно.
Це зручна можливість для написання більш читабельного коду, коли нам потрібно створити і повернути звідкись власний об’єкт типу Promise
.
Як ми знаємо, щоб створити власний об’єкт Promise
, ми можемо скористатися конструктором, в який передається функція-executor з двома параметрами-функціями: resolve
i reject
. Викликаючи ці параметри, ми можемо керувати станом нашого промісу в потрібний момент.
function doSomethingAsync() { return new Promise((resolve, reject) => { try { // some magic here resolve(); } catch (error) { reject(error); } }); }
Використовуючи новий статичний метод аналогічного результату можна уникнути додаткової вкладеності executor-а, що покращує читабельність.
function doSomethingAsync() { const {promise, resolve, reject} = Promise.withResolvers(); try { // some magic here resolve(); } catch (error) { reject(error); } return promise; }
Особливо це робить «чистішим» код, коли з певної причини ми хотіли керувати станом promise поза межами конструктора. Для цього потрібно було робити наступний «хак».
let resolve, reject; const promise = new Promise((resolveInternal, rejectInternal) => { resolve = resolveInternal; reject = rejectInternal; });
Розгляньмо більш практичний приклад. Описаний вище підхід часто використовується для асинхронних операцій, які не підтримують Promise-API. Наприклад, ми хочемо хочемо написати асинхронну функцію, яка за допомогою класу FileReader прочитає вміст файлу завантаженого, наприклад, з input типу file, і поверне вміст файлу як текст.
З конструктором Promise ми це зробимо наступним чином.
export function readFileAsText(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.onerror = () => reject(reader.error); reader.readAsText(file); }); }
Із withResolvers
це виглядатиме так:
export function readFileAsText(file) { const {promise, resolve, reject} = Promise.withResolvers(); const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.onerror = () => reject(reader.error); reader.readAsText(file); return promise; }
Особливо корисним новий метод може бути зі «стримами» чи іншими конструкціями, де дані приходять «порціями» (chunks).
На сьогодні цей метод уже доступний у практично всіх останніх версіях найпоширеніших браузерів. Стосовно «бекенду», то метод ще не доданий в Node.js, проте вже доступний в Deno 🙂
10 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів