9 полезных советов по Promise.resolve и Promise.reject

1
2822

Разбираемся, как работать с Promise.resolve, где лучше обрабатывать исключения Promise.reject, и какие еще есть хитрости в работе с асинхронным JS.

1. Вернуть Promise можно внутри .then

Возвращенный promise сразу будет готов к использованию в следующем .then:

2. Новый Promise создается при каждом .then

Если вы знакомы с цепочкой вызовов в JavaScript, то вы и так все знаете. Тем же, кто не в курсе, как это работает, некоторые вещи могут показаться не очевидными.

Каждый раз, когда вы используете .then или .catch к промисам, вы создаете новый. Новая сущность представляет собой композицию промиса и вызова .then или .catch, который был привязан.

На примере:

Взаимоотношения вызовов в коде выше можно описать такой схемой:

Схема Promise

Важно также, что promA, promB и promC – разные промисы, но родственные.

3. Оповещения о resolve/reject доступны везде

Если один промис используют несколько частей приложения, каждая часть будет оповещена, когда он получит состояние resolve/reject. Это также означает, что никто не сможет изменить ваш промис, так что его можно передавать без опаски.

В примере выше видно, что Promise по определению трудно изменяем.

4. Конструктор промисов не решает проблему

Многие разработчики повсеместно используют конструктор с мыслью, что все делают правильно. В действительности, API конструктора очень похоже на старое доброе Callback API.

Чтобы на самом деле отойти от callback’ов, необходимо уменьшить количество promise-конструкторов, которые вы используете.

Вот реальный случай использования конструктора:

Promise constructor понадобится только в том случае, когда вам нужно конвертировать callback в промис.

Однажды овладев этим способом создания промисов, велик будет соблазн использовать его всюду.

Вот пример ненужного использования конструктора:

А правильно так:

Заворачивание Promise в конструктор излишне и убивает всю пользу.

Если вы работаете с Node.js, присмотритесь к util-promisify. Эта маленькая штука поможет преобразовывать колбеки Node.js в промисы.

5. Использование Promise.resolve

Promise.resolve помогает сокращать некоторые сложные конструкции, как в примере:

У .resolve множество вариантов применения, один из них помогает конвертировать обычный JS-объект в promise:

Этот метод можно использовать как оболочку для значений, когда точно не известно промис это или простое значение.

6. Использование Promise.reject

Promise.reject может послужить заменой такому коду:

Функционал Promise.reject полностью оправдывает свое имя – он нужен чтобы отклонить промис.

В примере ниже reject используется внутри .then:

7. Использование Promise.all

Алгоритм работы Promise.all можно описать примерно так:

Следующий пример показывает, когда все промисы разрешаются:

Этот пример показывает, когда один из них терпит неудачу:

8. Обрабатывайте отказы уровнем выше

Оставляйте решение проблем с rejection родительским функциям. В идеале, обработка  отказов должна находиться в корне приложения, и все Promise.reject должны обрабатываться там.

Не стесняйтесь писать код вроде этого:

В этом случае, чтобы обработать rejection функции, нужно решить, разрешать работу как есть или продолжить обработку отказа. Есть небольшая уловка при работе с catch. Если вернуть Promise.reject в catch, то он будет отклонен.

Чтобы отклонить reject достаточно ничего не делать. Пусть это будет проблемой других функций. Чаще всего родительские функции имеют больше возможностей для обработки отказов, чем функция, в которой произошел reject.

Важно помнить, что если вы пишете .catch, значит, собираетесь обрабатывать ошибки. Если нужно перехватить отказ:

.then принимает второй параметр, который можно использовать для обработки ошибок. Это может напомнить then(x).catch(x), но эти обработчики по разному обрабатывают ошибки.

9. Избегайте нагромождений .then

Совет довольно прост: избегайте использования .then внутри .then или .catch.

Неверно:

Верно:

Порой бывает так, что необходимо множество переменных в пределах .then, и нет других вариантов, кроме цепочки вызовов.

Можно использовать ES6 подход к деструктуризации и Promise.all:

Больше полезного по JS:

Интересуетесь веб-разработкой?

Подпишитесь на нашу рассылку, чтобы получать больше интересных материалов:

И не беспокойтесь, мы тоже не любим спам. Отписаться можно в любое время.




1 комментарий

Оставьте комментарий