JavaScript Promises – All You Need to Know to Get Started.
обязательство или обещание, следует обратить внимание читателей на неоднозначность точного перевода с английского языка слова promise
promise переведен как обещание. Однако по смыслу, который вложили в этот термин разработчики языка, – это именно обязательство! Имеется в виду, что создавая обязательство
Поэтому именно термин обязательство я буду использовать для изложения материалов в этой статье.
Обязательства (обещания) Promise – одно из недавно введенных в JavaScript средств языка, которое предоставляет более простой, интуитивно понятный способ работы с асинхронным кодом. Это руководство поможет вам разобраться, что такое обязательства Promise, как их создавать, и как использовать вместе с функциями-обработчиками. В конце вы также узнаете, как работать с несколькими обязательствами в вашем коде.
Содержание
- Вступление
- Создание обязательства Promise
- Исполнение и отклонение обязательств promise с использованием статических методов
- Четыре состояния обязательств Promises
- Обработка состояний обязательств Promises с помощью специальных функций-обработчиков
- Функция-обработчик catch()
- Методы объекта Promise
- Заключение: обязательства JavaScript
Вступление
Что такое обязательство Promise в JavaScript? Обязательства Promise – это объекты, которые в конечном счете предоставляют (возвращают) некоторое значение. Когда вы создаете новое обязательство вы заранее не знаете какое именно значение вы можете получить: это могут быть данные из внешнего API, или сообщение об ошибке. Отметим, основную особенность использования обязательств, как специфичного средства языка: вы получите ожидаемое значение в некотором будущем, в случае если созданное вами обязательство Promise будет выполнено или отклонено. При следующий за обязательством promise этом код не блокируется им, не ожидает завершения его работы. Эта возможность значительно упрощает написание асинхронных приложений и делает работу и разработку более контролируемыми.
Представьте, что вами используется приложение, которому при запуске необходимо получить данные из некоторого внешнего API. Проблема в том, что вы не знаете точно, когда именно получите эти данные. Иногда их можно получить достаточно быстро. Но чаще этот процесс может занять некоторое неопределенное время. Как написать приложение, чтобы учесть эту неопределенность?
Одним из возможных вариантов решения этой задачи – проверка готовности данных в определенные промежутки времени. Приложение будет делать это пока, наконец, не получит нужные данные. Этот подход не является чистым, с точки зрения программирования, и тем более эффективным. Другой вариант – использовать такое средство языка Javascript как обязательства Promise. Вы можете использовать обязательства Promise для обращения к внешнему API. И когда это обязательство завершено, то есть разрешено (удовлетворено) или отклонено, то сможете обновить состояние своего приложения.
Как пояснить это проще? Когда обещание Promise завершено settled, то оно может быть исполнено fulfilled либо отклонено rejected, при этом интерпретатор Javascript автоматически запускает события, которые вы можете прослушивать с помощью специальных методов (функций-обработчиков). При этом вам не нужно регулярно проверять статус данных, как в первом решении.
Вместо этого ваши обработчики автоматически выполнят любой код в нужный момент времени, когда Promise вернет ожидаемые данные. Я надеюсь теперь вам стал понятен смысл использования механизма обязательств Promise.
Создание обязательства Promise
Это была теория, а теперь мы перейдем к практике. Для создания объекта Promise используется конструктор Promise()
. С учетом синтаксиса языка Javascript его использование подразумевает также наличие ключевого слова new
, за которым непосредственно помещается выражение конструктора: Promise()
. Конструктор принимает только один параметр – функцию, называемую исполнителем executor. Функция-исполнитель вызывается автоматически при создании и инициализации объекта обязательства Promise.
В свою очередь функция-исполнитель принимает два параметра: resolve
и reject
, оба являются функциями обратного вызова. Когда обязательство разрешено – вызывается функция обратного вызова resolve
. Это состояние соответствует тому, что код помещенный в Promise, был успешно выполнен (без ошибок). В случае если возникает какая-либо ошибка, и Promise отклоняется, то вызывается функция обратного вызова reject
.
// Пример синтаксиса Promise const myPromise = new Promise(function(resolve, reject) { // ... ваш код }) // Пример синтаксиса Promise с использованием стрелочной функции const myPromise = new Promise((resolve, reject) => { // ... ваш код })
Исполнение и отклонение обязательств promise с использованием статических методов
Если вы хотите, чтобы обязательство Promise возвращало какие-либо данные, то вы должны передавать их в качестве аргументов при вызове функции resolve
. Например, если код в обязательстве обращается к внешнему API, то вы, соответственно, передаете в функцию resolve
возвращаемые этим API данные. А в случае возникновения ошибки вы передаете информацию об ошибке или сообщение об ошибке в функцию обратного вызова reject
.
// Пример синтаксиса Promise const myPromise = new Promise(function(resolve, reject) { // Удовлетворенный Promise получает сообщение в качестве данных resolve('Success: promise resolved.') // Если случилась ошибка if (error) { // Отклоненный Promise получает сообщение в качестве данных reject('Failure: promise rejected') } }) // инициализируем Promise myPromise(); // Пример синтаксиса Promise с использованием стрелочной функции const myPromise = new Promise((resolve, reject) => { // Удовлетворенный Promise получает сообщение в качестве данных resolve('Success: promise resolved.') // Если случилась ошибка if (error) { // Отклоненный Promise получает сообщение в качестве данных reject('Failure: promise rejected') } }) // инициализируем Promise myPromise();
Если вы выполните полученный код, в консоли, то объект Promise сможет передать полученные данные функциям-обработчикам, которые вы подключили к обязательству myPromise. Есть еще две вещи о которых вы должны знать при создании своих обязательств Promise. Во-первых, вы можете передать ссылку на объект Promise переменной, а затем вызвать ее. Это похоже на использование функционального выражения.
// Создаем Promise #1: передаем ссылку на него переменной const myPromise = new Promise((resolve, reject) => { // Удовлетворенный Promise получает сообщение в качестве данных resolve('Success: promise resolved.') // Если случилась ошибка if (error) { // Отклоненный Promise получает сообщение в качестве данных reject('Failure: promise rejected') } }) // инициализируем Promise myPromise();
Рассмотрим еще один вариант – возвращаем объект обязательства Promise из функции. Далее когда вы захотите использовать его в своем коде, то вызываете соответствующую функцию, которая инициализирует и возвращает объект Promise. При этом ваш код будет работать точно так же, как в примере выше.
Если вы хотите вернуть объект Promise, то вам необходимо использовать ключевое слово
new
перед конструктором Promise.
// Создаем Promise #2: возвращаем его из функции function myFunc() { // Возвращаем новый Promise return new Promise(function(resolve, reject) { // Удовлетворенный Promise получает сообщение в качестве данных resolve('Success: promise resolved.') // Если случилась ошибка if (error) { // Отклоненный Promise получает сообщение в качестве данных reject('Failure: promise rejected') } }) } // Вызываем функцию myFunc() для инициализации Promise внутри нее myFunc()
Четыре состояния обязательств Promises
И так, мы знаем, что обязательства Promises или удовлетворяются (разрешаются) resolve или отклоняются rejected. По сути смысла этих терминов уже понятно, что они непосредственно связаны с состояниями, в которых может находится обязательство Promises, а точнее его объект (экземпляр). В свою очередь эти состояния определяют будет ли вызвана соответствующая функция-обработчик при переходе обязательства соответствующее состояние.
Однако, обязательства Promises могут находится в четырех состояниях:
-
Первое состояние – ожидание решения
pending
. Это начальное состояние, когда вы создаете обязательство, а точнее экземпляр объекта Promises и инициализируете его. Это состояние соответствует тому, что обещание пока не удовлетворено (разрешено) resolve, но и не отклонено rejected. -
Второе состояние – удовлетворено
fulfilled
, то есть обязательство было разрешено resolve и его код успешно выполнен. -
Третье состояние – отклонено
rejected
. Это означает, что возникла некоторая проблема, которая помешала успешному выполнению кода обязательства. -
Четвертое состояние – урегулировано
settled
. Это означает, что работа обязательства в общем завершена (его код полностью закончил свою работу) и оно в последствии было удовлетворено либо отклонено.
Обработка состояний обязательств Promises с помощью специальных функций-обработчиков
Теперь мы знаем как создать объект Promise, а также о четырех его возможных состояниях. Необходимо разобраться как работать с данными, возвращаемыми объектом Promise (результатом его работы), а точнее данными, передаваемыми в функции обратного вызова resolve
и reject
. И так в игру вступают методы объекта обязательства then()
, catch()
и finally()
. Эти методы являются по сути функциями-обработчиками, которые вы можете присоединить к конкретному экземпляру объекта обязательства для прослушивания его событий.
И так вы создали и инициализировали новый объект Promise, после чего соответствующее обязательство в конечном счете будет урегулировано settled
, то есть удовлетворено или отклонено. Поэтому в любом случае будет автоматически вызван один из перечисленных выше обработчиков. То есть когда из объекта Promise возвращаются данные, они будут переданы соответствующим обработчикам в зависимости от состояния, в котором будет находится объект (экземпляр) обязательства.
Если вы хотите поработать с данными, возвращаемыми из Promise, то функции-обработчики именно то, что нам нужно. Например, вы можете поместить в эти обработчики логику для обновления информации, отображаемой вашим приложением, данными, получаемыми из внешнего API.
Но что делать, если вы не используете ни один из этих обработчиков? Код обязательства Promise все равно будет выполняться после того, как вы его вызовете. И данные (результат работы кода обязательства) не будут обработаны, то есть будут заблокированы внутри объекта Promise. Вот зачем необходимы функции-обработчики. Они похожи на мессенджеры, которые передают сообщения (данные) от объекта Promise далее по цепочке.
Функция-обработчик then()
Начнем с функции-обработчика then()
, которая обычно используется для обработки наступления fulfilled
состояния. Для того, чтобы использовать then()
или вообще любой другой обработчик событий обязательства, вы должны присоединить его к объекту Promise при его инициализации (вызове). Следующий ниже пример синтаксиса соответствует передаче ссылке на объект обязательства по имени, а затем прикреплении к нему функции-обработчика .then()
.
// Создаем обещание Promise const myPromise = new Promise((resolve, reject) => { // Имитируем задержку setTimeout(function() { // Удовлетворенный Promise получает сообщение в качестве данных resolve('Promise has been resolved!') }, 1000) }) // инициализируем (вызываем) myPromise и присоединяем к нему обработчик then() // передаем функцию обратного вызова в обработчик then() // передаем в функцию обратного вызова один параметр myPromise.then((receivedData) => { // выводим в консоли данные полученные с помощью Promise console.log(receivedData) }) // В консоли получим: // 'Promise has been resolved!'
Когда обязательство будет выполнено, не важно удовлетворено или отклонено, данные (результат работы кода) будут переданы в обработчик then()
и могут быть далее обработаны по вашему усмотрению. В примере выше эти данные передаются через функцию обратного вызова resolve()
, которая вызывается в коде обязательства. Таким образом, если вы хотите получить доступ к данным, результату работы кода обязательства, вам нужно передать их в функцию обратного вызова, и далее они будут доступны в обработчике then()
.
Функция обратного вызова resolve()
принимает только один параметр (возвращаемые данные). И таким образом любые данные, возвращаемые обязательством после его удовлетворения resolve, будут доступны в функции-обработчике.
У обработчика then()
есть одна интересная особенность – вы можете использовать его для обработки возвращаемых из кода обязательства данных для состояния rejected (отклонено). И как же нам обеспечить обработку обоих состояний?
Дело в том, что первый параметр, передаваемый в функцию-обработчик, должен быть функций обратного вызова, которая будет использоваться для обработки состояния fulfilled. А если вы хотите, чтобы было обработано состояние, при котором обязательство отклонено rejected, то вам нужно просто передать в в then()
вторую функцию обратного вызова.
Вторая функция обратного вызова, по аналогии, тоже принимает только один параметр. Используя его вы можете получить доступ к любой информации об ошибках, переданной из объекта обязательства Promise. Тем не менее обработчик then()
в основном используется для обработки состояния fulfilled, и реже для rejected. Так как передать функцию обратного вызова для обработки отклоненного состояния rejected «трудно» без передачи первой, ответственной за состояние fulfilled.
// Создаем Promise const myPromise = new Promise((resolve, reject) => { // Имитируем задержку выполнения кода setTimeout(function() { // Отклоненный Promise получает сообщение в качестве данных reject('Promise has been rejected...') }, 1000) }) // инициализируем myPromise и присоединяем к нему обработчик then() // передаем функцию обратного вызова в обработчик then() // передаем в функцию обратного вызова один параметр myPromise.then((receivedData) => { // Это первая функция обратного вызова для состояния 'fulfilled' // выводим в консоли данные полученные с помощью Promise console.log(receivedData) }, (error) => { //Примечание. Не забудьте разделить функции обратного вызова для обработки состояний удовлетворения и отклонения обязательства запятой, если вы все еже решите использовать функцию-обработчика
then()
для обработки обоих состояний.Функция-обработчик catch()
Далее рассмотрим метод
catch()
, который используется для обработки состояния reject, то есть обязательство было отклонено. Использование этого обработчика, как и доступ к любым данным, переданным в него, аналогично обработчикуthen()
. Если вы хотите использовать его и присоединить к Promise, то рекомендуется прикреплять его после обработчикаthen()
. Когда вы присоединяете его, вы должны передать ему функцию обратного вызова, которая принимает также только один параметр. Когда обещание Promise отклоняется, любые данные, переданные в обработчикreject()
внутри объявления Promise, будут доступны через ее единственный параметр.// Пример с Reject #1: без then() // Создаем Promise const myPromise = new Promise((resolve, reject) => { // Имитируем задержку выполнения кода setTimeout(function() { // Отклоненный Promise получает сообщение в качестве данных reject('Promise has been rejected...') }, 1000) }) // инициализируем myPromise и присоединяем к нему обработчик catch() // передаем функцию обратного вызова в обработчик catch() // передаем в функцию обратного вызова один параметр myPromise.catch((error) => { // выводим в консоли данные полученные с помощью Promise console.log(error) }) // В консоли получим: // 'Promise has been rejected...' // Пример с Reject #1: с then() // Создаем Promise const myPromise = new Promise((resolve, reject) => { // Имитируем задержку выполнения кодаy if (error) { // Удовлетворенный Promise получает сообщение в качестве данных reject('Promise has been rejected...') } else { resolve('Promise has been resolved.') } }) // инициализируем myPromise и сразу присоединяем обработчик then() // передаем в функцию обратного вызова один параметр // далее присоединяем обработчик catch(), и также передаем // в него функцию обратного вызова с одним параметром myPromise .then((receivedData) => { // выводим в консоли данные полученные с помощью Promise console.log(receivedData) }) .catch((error) => { // выводим в консоли сообщение об ошибке, полученное из Promise console.log(error) })Функция-обработчик finally()
Метод
finally()
это последняя функция-обработчик, которую мы рассмотрим. Особенностью этого обработчика является то, что он будет вызываться каждый раз при переходе Promise в состояниеsettled
. При этом он будет вызван независимо от того, как закончил работу код Promise, то есть с переходом в состояниеfulfilled
илиrejected
. Использование этого обработчика может быть полезно, если вы хотите что-то сделать независимо от конечного состояния обязательства.Обработчик
finally()
используется так же, как и другие функции-обработчикиthen()
иcatch()
. Вы прикрепляете его к объекту Promise, когда вызываете его.finally()
обычно прикрепляется в качестве самого последнего обработчика, послеthen()
иcatch()
. В отличие от двух предыдущих, этот обработчик не требует никаких параметров, так как в него ничего не передается.const myPromise = new Promise((resolve, reject) => { // Имитируем задержку выполнения кода setTimeout(function() { // Удовлетворенный Promise получает сообщение в качестве данных resolve('Promise has been resolved.') }, 1000) }) // инициализируем myPromise и сразу присоединяем обработчик then() // далее присоединяем обработчик catch() // далее присоединяем обработчик finally() myPromise .then((receivedData) => { // выводим в консоли данные полученные с помощью Promise console.log(receivedData) }) .catch((error) => { // выводим в консоли сообщение об ошибке, полученное из Promise console.log(error) }) .finally(() => { // выводим в консоли информационное сообщение console.log('Promise is done.') }) // В консоли получим: // 'Promise has been resolved.' // 'Promise is done.'Методы объекта Promise
Работать с обязательствами в JavaScript достаточно просто когда в вашем коде их используется всего одно или два. Но что, если вам необходимо обрабатывать сразу несколько обязательств? К счастью JavaScript предоставляет несколько методов, которые упрощают эту задачу. Это такие методы как
all(),
allSettled(),
race()
иany()
.Все эти методы в качестве параметров принимают итерируемый объект, например массив. Этот объект содержит обязательства , которые вы хотите вызвать и обработать данные, полученные из них. Разница в том, что каждый из этих методов работает по-своему и приводит к получению разных результатов. Итак, давайте разберемся с каждым из них.
Promise.all()
Когда вы передадите в метод
Promise.all()
обязательства, то он попытается выполнить их по очереди и разрешить их все. В случае если все переданные обязательства будут удовлетворены (разрешены) то методPromise.all()
вернет одно обязательство, содержащее все полученные значения. Получить доступ к этому значению, можно присоединив обработчикthen()
к методуPromise.all()
, передав ему соответствующую функцию обратного вызова.Если происходит так, что одно или несколько из обязательств переданных в метод
Promise.all()
отклоняются, то сразу возвращается значение из первого отклоненного обязательства. Это важно помнить. И так если одно из обязательство «терпит неудачу» тоPromise.all()
, вернет только значение переданное из первого отклоненного обязательства. То есть метод не будет возвращать данные из любых до этого удовлетворённых (разрешенных) обязательств.// Пример #2: все обязательства Promises разрешены // создаем первое обязательство Promise которое будет разрешено const myPromiseOne = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Удовлетворенный Promise получает сообщение в качестве данных resolve('myPromiseOne has been resolved.') }, 500) }) // создаем второе обязательство Promise которое будет разрешено const myPromiseTwo = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Удовлетворенный Promise получает сообщение в качестве данных resolve('myPromiseTwo has been resolved.') }, 1000) }) // Используем Promise.all() для обработки всех обязательств Promises Promise.all([myPromiseOne, myPromiseTwo]) .then((data) => { // выводим в консоли данные полученные для случая когда Promise разрешен console.log(data) }) .catch((error) => { // Выводим в консоли сообщение об ошибке если Promise отклонен console.log(error) }) // Выведет в консоли: // [ // 'myPromiseOne has been resolved.', // 'myPromiseTwo has been resolved.' // ] // Пример #2: средний Promise будет отклонен // создаем первое обязательство Promise которое будет разрешено const myPromiseOne = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Удовлетворенный Promise получает сообщение в качестве данных resolve('myPromiseOne has been resolved.') }, 500) }) // создаем второе обязательство Promise, которое будет отклонено const myPromiseTwo = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Отклоненный Promise получает сообщение в качестве данных reject('myPromiseTwo has been rejected.') }, 1000) }) // создаем третье обязательство Promise, которое будет разрешено const myPromiseThree = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Удовлетворенный Promise получает сообщение в качестве данных resolve('myPromiseThree has been resolved.') }, 1500) }) // Используем Promise.all() для обработки всех обязательств Promises Promise.all([myPromiseOne, myPromiseTwo, myPromiseThree]) .then((data) => { // выводим в консоли данные полученные для случая когда Promise разрешен console.log(data) }) .catch((error) => { // Выводим в консоли сообщение об ошибке если Promise отклонен console.log(error) }) // Выведет в консоли: // 'Error: myPromiseTwo has been rejected' // !! Notice that the data from myPromiseOne that was resolved // before the myPromiseTwo was rejected are missingПримечание. Не забудьте добавить обработчик
catch()
при использовании методаPromise.all()
. Или добавьте второй обратный вызов в методthen()
. В противном случае вы не получите никаких данных об ошибках, если одно из обещаний будет отклонено.Promise.allSettled()
Рассмотрим еще один очень полезный метод
Promise.allSettled()
, который можно использовать для обработки нескольких обязательств. Отметим, что методPromise.allSettled()
работает аналогичноPromise.all()
. Он также попытается разрешить все переданные в него обязательства.Разница в том, что если одно из обязательств отклоняется, то
Promise.allSettled()
все равно ожидает выполнение кода других обязательств. Таким образом, когда работа всех обязательств завершена, то есть они находятся в состоянии settled, только тогда методPromise.allSettled()
вернет все значения, полученные от переданных в него обязательств. То есть вернет все значения, независимо от того, отклонено rejected или удовлетворено resolve какое-либо из этих обещаний. Это его самое главное отличие от методаPromise.all()
.Значения, возвращаемые методом,
Promise.allSettled()
имеют вид объектов. Каждый объект кроме возвращаемых данных содержит статус (состояние), с которым код обязательства закончил работу, то естьfulfilled
илиrejected
. Если обязательство разрешено, то соответствующий объект будет содержать полеvalue
– значение, полученное из него. Если обязательство отклонено, то соответствующий объект содержит полеreason
– данные об ошибке.Это делает его использование в большинстве случаев лучшим выбором, чем метод
Promise.all()
. Кроме того вам не нужно беспокоиться о потере значений, получаемых от всех удовлетворенных (разрешенных) обязательств только из-за сбоя в работе одного из них. Вместо этого вы получите все значения как от тех обязательств, которые были разрешены resolve, так и от тех, которые были отклонены rejected.// создаем первое обязательство Promise которое будет разрешено const myPromiseOne = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Удовлетворенный Promise получает сообщение в качестве данных resolve('myPromiseOne has been resolved.') }, 500) }) // создаем второе обязательство Promise которое будет отклонено const myPromiseTwo = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Отклоненный Promise получает сообщение в качестве данных reject('myPromiseTwo has been rejected!') }, 1000) }) // создаем третье обязательство Promise которое будет разрешено const myPromiseThree = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Удовлетворенный Promise получает сообщение в качестве данных resolve('myPromiseThree has been resolved.') }, 1500) }) // Используем Promise.allSettled() для обработки всех обязательств Promises Promise.allSettled([myPromiseOne, myPromiseTwo, myPromiseThree]) .then((data) => { // выводим в консоли данные полученные от разрешенных обязательств console.log(data) }) // Выведет в консоли: // [ // { // status: 'fulfilled', // value: 'myPromiseOne has been resolved.' // }, // { // status: 'rejected', // reason: 'myPromiseTwo has been rejected!' }, // { // status: 'fulfilled', // value: 'myPromiseThree has been resolved.' // } // ]Promise.race()
Метод
Promise.race()
делает именно то, что предписывает его название (race – гонка). Для работы этого метода требуется как минимум пара обязательств, которые будут «участвовать в гонке». Это означает, что метод в качестве результата вернет новое обязательство, как только одно из переданных ему будет удовлетворено или отклонено. Это новое обязательство будет содержать либо значение в полеvalue
, то есть какие либо данные, либо сообщение об ошибке в полеreason
. Возвращаемое значение будет определяться тем, какое из переданных в метод обязательств будет выполнено быстрее всех, при этом не важно, удовлетворено оно будет либо отклонено.// создаем первое обязательство Promise которое будет разрешено const myPromiseOne = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Удовлетворенный Promise получает сообщение в качестве данных resolve('myPromiseOne has been resolved.') }, 500) }) // создаем второе обязательство Promise которое будет разрешено const myPromiseTwo = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Удовлетворенный Promise получает сообщение в качестве данных resolve('myPromiseTwo has been rejected!') }, 1000) }) // создаем третье обязательство Promise которое будет разрешено const myPromiseThree = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Удовлетворенный Promise получает сообщение в качестве данных resolve('myPromiseThree has been resolved.') }, 1500) }) // Используем Promise.race() для обработки всех обещаний Promises Promise.race([myPromiseOne, myPromiseTwo, myPromiseThree]) .then((data) => { // выводим в консоли данные полученные от разрешенных обязательств console.log(data) }) .catch((error) => { // выводим в консоли сообщения полученные от отклоненных обязательств console.log(error) }) // В консоли выведет: // 'myPromiseOne has been resolved.'Примечание: аналогично
Promise.all()
, к методуPromise.race()
возможно подключение обработчикаcatch()
. Или по аналогии добавить вторую функцию обратного вызова в методthen()
. В противном случае вы не получите никаких сообщений об ошибке, если первое переданное для обработки в метод обязательство будет отклонено.Promise.any()
Метод
Promise.any()
по сути аналогиченPromise.race()
. Разница между ними в том, чтоPromise.any()
игнорируют любые полностью выполненные, но отклоненные обязательства. Он вернет значение только первого выполненного и удовлетворенногоfulfilled
обязательства.// создаем первое обязательство Promise которое будет отклонено const myPromiseOne = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Отклоненный Promise получает сообщение в качестве данных reject('myPromiseOne has been resolved.') }, 500) }) // создаем второе обязательство Promise которое будет отклонено const myPromiseTwo = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Отклоненный Promise получает сообщение в качестве данных reject('myPromiseTwo has been rejected!') }, 1000) }) // создаем первое обязательство Promise которое будет разрешено const myPromiseThree = new Promise((resolve, reject) => { // имитируем задержку в выполнении кода setTimeout(function() { // Удовлетворенный Promise получает сообщение в качестве данных resolve('myPromiseThree has been resolved.') }, 1500) }) // Используем Promise.all() для обработки всех обязательств Promises Promise.any([myPromiseOne, myPromiseTwo, myPromiseThree]) .then((data) => { // выводим в консоли данные полученные от разрешенных обязательств console.log(data) }) .catch((error) => { // Выводим в консоли сообщения полученные от отклоненных обязательств console.log(error) }) // Выведет в консоли: // 'myPromiseThree has been resolved.'Примечание. На момент написания этой статьи Promise.any() находится на Stage 3 предложения. Это означает, что это нестабильная часть языка JavaScript и метод все еще является экспериментальным и поддерживается не всеми браузерами.
Заключение: обязательства JavaScript
Поздравляю! Вы только что закончили читать статью об обязательствах Promise в JavaScript. Если вы внимательно ознакомились с содержанием этой статьи, то теперь знаете, что такое обязательства, как их создавать, по какому принципу он удовлетворяются или отклоняются. Вы узнали основы использования функций-обработчиков
then()
,catch()
иfinally()
, предназначенных для обработки данных, возвращаемых выполненными обязательствами Promises.И, наконец, вы теперь в состоянии использовать другие обязательств такие как
Promise.all()
,Promise.allSettled()
,Promise.race()
иPromise.any()
, которые используются для работы с несколькими обязательствами одновременно. Теперь вы хорошо подготовлены для написания более чистого и интуитивно понятного асинхронного кода JavaScript. А также можете, наконец, попрощаться с адом вложенных обратных вызовов.
Спасибо за информацию буду знать.