Новий метод Promise.withResolvers тепер доступний у браузерах

💡 Усі статті, обговорення, новини про Front-end — в одному місці. Приєднуйтесь до Front-end спільноти!

Недавно у 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 🙂

👍ПодобаєтьсяСподобалось6
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
новий метод може бути зі «стримами» чи іншими конструкціями

Чого раптом у багатьох «стрІми» стають «стрИмами»... 😒

З конструктором Promise ми це зробимо наступним чином.

І виглядає це набагато краще та лаконічно, ніж той «withResolvers», ще й краще буде мініфікуватися, бо змінним можна скоротити імена, на відміну від полів. Краще б повертали вже масив чи додали в цей об’єкт ще і ітератор, що можна було

const [promise, resolve, reject] = Promise.withResolvers();

Щодо літери и — це так зване правило девʼятки, згідно з яким у запозичених словах пишемо «и» на місці «і» після 9-ти приголосних («д», «т», «з», «с», «ц», «ж», «ш», «ч», «р»).

Там багато винятків для слів «засвоєних українською мовою», які не слідують цьому правилу, так що не зрозуміло чому «стрім» не може бути вже таким винятком, якщо в реальності (чи по гуглу) мова вже його засвоїла в такій формі, а не по правилу 100 річної давності. Хоча це звісно питання до тих, хто оновляє правописи.

Це правило тільки для мов, які не розрізняють свої «і» та «и». Англійська розрізняє, тому уніфікація може призвести до небажаної омоніміі (як beach/bitch).

А ти дивився в що твій ітератор перетворюється під час компіляції байткоду перед тим як казати що було б «краще»?

А ти дивився в що твій ітератор перетворюється під час компіляції байткоду

До чого тут взагалі байткод?
Щодо транспіляції, то це ще ES2015, 10 років вже пройшло- віслюки давно на цвинтарі. Олсо, хочеш сказати що зараз у всьому проекті включаючи модулі не буде ні одного ітератора? 🙃

Як це до чого тут байткод? Ти ж за перформанс переживаєш, мініфікацію декількох символів захотів. Є різниця між 50-80 і 3-5 інструкціями байткоду? Чи може ще скажеш, що var застарілі?))

Будуть звісно, тому що в певних сценаріях без ітераторів не обійтись по тим чи іншим причинам і це звичайна частина будь якої мови програмування, але застосовувати її треба там, де вона виконує свої задачі найкраще, а не пхати всюди, бо так Дмитро на dou написав.

function doSomethingAsync() {
   new Promise((resolve, reject) => {
       try {
           // some magic here
           resolve();
       } catch (error) {
           reject(error);
       }
   });
}

тут мабуть хотілось повернути проміс, як в наступному прикладі?

Підписатись на коментарі