WEBYK WEBYK Індивідуальні OnLine уроки з web технологій
+38 093 766 39 11
oleggpann@gmail.com

Что не так с Promise.allSettled () и Promise.any () ❓

Недавно я прочитал статью о комбинаторах Promise в блоге v8. В нем рассказывается о двух новых методах API Promise: Promise.allSettled () и Promise.any (). И я чувствую разочарование. Дизайн этих методов выглядит мне несовместимым с текущим API Promise. Позвольте мне поделиться своим мнением ниже.

Promise.allSettled

Согласно статье: Promise.allSettled дает вам сигнал, когда все входные обещания выполнены, что означает, что они либо выполнены, либо отклонены. Использование -case - отправить несколько вызовов API и дождаться, пока все закончится:const promises = [   fetch('/api-call-1'),   fetch('/api-call-2'),   fetch('/api-call-3'), ];  await Promise.allSettled(promises);  removeLoadingIndicator();Конечно, это полезно. Но эту задачу можно легко решить с помощью .map () и Promise.all (). Изменение минимально:const promises = [   fetch('/api-call-1'),   fetch('/api-call-2'),   fetch('/api-call-3'), ].map(p => p.catch(e => e)); // <-- the only change  await Promise.all(promises);  removeLoadingIndicator();Стоит ли реализовывать новый метод ядра, который можно решить в несколько строк кода? На мой взгляд, это особенность библиотеки, а не основной метод API. Но более важно то, что Promise.allSettled приносит дополнительный уровень абстракции. В отличие от Promise.all он выполняет массив обертывающих объектов {status, reason} вместо чистых значений обещаний. Как разработчик, мне это не нравится. Я ожидаю, что методы с похожими именами .all () /. AllSettled () ведут себя сходным образом. Но они этого не делают. Более того, код с Promise.allSettled поощряет позднюю обработку ошибок. Ошибки должны быть отфильтрованы из конечного результата вместо традиционного блока catch. Это, в свою очередь, имеет следующие недостатки: 

  • ошибки не обрабатываются немедленно, в момент их возникновения. В случае нескольких связанных ошибок вы не можете узнать, какая из них была исходной. И журнал будет содержать неправильные метки времени.
  • ошибки не обрабатываются, если хотя бы одно обещание ожидает навсегда.

Используя текущий Promise.все вы избежите такого вещи.

Promise.any

Promise.any дает вам сигнал, как только одно из обещаний выполняется. Другими словами, Promise.any - это Promise.race, который игнорирует отклонения. Вариант использования - проверить несколько конечные точки и взять данные из первого успешного:const promises = [   fetch('/endpoint-a').then(() => 'a'),   fetch('/endpoint-b').then(() => 'b'),   fetch('/endpoint-c').then(() => 'c'), ]; try {   const first = await Promise.any(promises); } catch (error) {   // All of the promises were rejected.   console.log(error); }Я согласен, иногда это может быть полезно. Но как часто? В скольких проектах вы использовали шаблон «несколько параллельных запросов к одинаковым конечным точкам для одних и тех же данных»? Не стесняйтесь поделиться в комментариях. Но с моей точки зрения - не очень часто. Разве для сообщества не может быть более полезным получить встроенную реализацию Promise.each () или Promise.delay () bluebird? Более того, Promise.any представляет новый тип ошибок - AggregateError. Такая ошибка содержит ссылки на другие ошибки, если все обещания отклонены. Еще один подход к обработке ошибок! Он отличается от Promise.allSettled, где ошибки извлекаются из результата успеха. Он также отличается от Promise.all / Promise.race, который отклоняется только с помощью экземпляра Error. Как будет выглядеть JavaScript, если каждый новый метод Promise API будет представлять новый способ обработки ошибок? Хотя предложение находится на очень ранней стадии, меня беспокоит направление. На основе текущего API Promise реализация Promise.any немного сложна, но на самом деле это две строки кода:const reverse = p => new Promise((resolve, reject) => Promise.resolve(p).then(reject, resolve)); Promise.any = arr => reverse(Promise.all(arr.map(reverse)));Может быть, хранить его в библиотеке?

Несоответствие

Почему Promise.all и Promise.race такие красивые? Потому что они ведут себя очень непротиворечиво и аналогично обычным обещаниям: выполняйте только со значением и отклоняйте только с ошибкой. Никаких упакованных значений, никаких накопленных ошибок, никакой дополнительной сложности. Почему Promise.allSettled и Promise.any настолько странны для меня? Promise.allSettled выполняет с массивом объектов со статусом и причиной, заключающими в себе значения обещаний. И отклоняет ... никогда. Promise.any выполняет с одним значением, но игнорирует промежуточные отклонения. Только если все обещания будут отклонены, он отвергает с накопленной причиной, охватывающей все основные причины. Эти новые подходы действительно трудно представить в моей голове. Поскольку они сильно отличаются от текущего API Promise. Я предполагаю, что популярный вопрос собеседования в 2020 году: в чем отличие этих четырех методов? 

  • Promise.all ()
  • Promise.allSettled ()
  • Promise.race ()
  • Promise.any ()

Несмотря на то, что это крутой вопрос, я не думаю, что базовый API должен поощрять такую ​​сложность.

Именование

Я также разочарован именами. Четыре метода с немного отличным поведением должны иметь довольно четкие имена. В противном случае мне придется перепроверять MDN каждый раз, когда я встречаю их в коде. Из предложения Promise.any:

Он четко описывает, что он делает

Позвольте мне не согласиться. Для меня имя Promise.any сбивает с толку: 

  • Будет ли оно выполнено, если выполнит какое-либо из обещаний? Да.
  • Отклонит ли он одно из обещаний? Нет.
  • Соглашатся ли они, если выполнятся какие-либо из обещаний? Это зависит.
  • Чем он отличается от Promise.race? Хм ..

Я думаю, что имя каждого метода должно явно определять условие, когда метод выполняется. Я бы предложил следующее соглашение об именах:Promise.all        -> Promise.allFulfilled Promise.allSettled -> Promise.allSettled Promise.race       -> Promise.oneSettled Promise.any        -> Promise.oneFulfilledОн отражает четыре возможных комбинации состояний обещания. Это объясняет, почему в предложении упоминаются эти методы как комбинаторы. Конечно, такое переименование невозможно, так как Promise.all и Promise.race уже были найдены и используются во многих приложениях. Но для новых методов было бы очень полезно иметь некоторую стратегию именования.

Отклоненные отклонения

В целом я не вдохновлен концепцией непринятых отклоненных отклонений. Фактически, новый Promise API предоставляет способ игнорировать ошибки в коде: 

  • Promise.allSettled никогда не отклоняет.
  • Promise.any отклоняет только если все обещания отклонены.

В настоящее время никакой другой основной JavaScript API не делает этого. Единственный способ игнорировать ошибку - вручную обернуть ее в try..catch / .catch () с пустым телом. И напишите комментарий, почему вы игнорируете ошибку здесь, иначе eslint предупредит вас. Я думаю, что базовый API должен раскрывать все ошибки. Это всегда решение разработчика, обрабатывать ли ошибку или нет. Это должно быть явно для других разработчиков, читающих код. Только представьте, сколько часов будет отлажено из-за неточного использования проглоченных отказов! Особенно когда речь идет о стороннем коде - когда что-то не работает и не выдается никаких ошибок.

Заключение

Я использую обещания каждый рабочий день. Как и многие другие разработчики. Я люблю JavaScript за его асинхронную природу. Наличие понятного и интуитивно понятного API позволяет мне быстрее решать задачи и работать более продуктивно. Вот почему я считаю, что Promise API следует очень тщательно обрабатывать и менять. Спасибо за чтение и добро пожаловать в комментарии.

Теги

Обещания по кодированию Javascript Программирование Hackernoon Главная история Promiseallsettled Promiseany Последние технические истории Продолжить обсуждение
Источник: https://hackernoon.com/whats-wrong-with-promiseallsettled-and-promiseany-yfib64aiv

Якщо у вас виникли питання, вбо ви бажаєте записатися на індивідуальний урок, замовити статтю (інструкцію) або придбати відеоурок, пишіть нам на:
скайп: olegg.pann
telegram, viber - +380937663911
додавайтесь у телеграм-канал: t.me/webyk
email: oleggpann@gmail.com
ми у fb: www.facebook.com/webprograming24
Обов`язково оперативно відповімо на усі запитіння


Поділіться в соцмережах



Подобные статьи:


facebook
×
Підришіться на цікаві пости.
Підписатись