Многообещающая функция асинхронного Javascript

Обещания могут быть сложным делом. Как однопоточный язык, Javascript сильно выигрывает от асинхронности, обеспечиваемой промисами. Во многих отношениях обещания необходимы для правильного выполнения кода и загрузки ресурсов. Это то, что позволяет программе извлекать ресурсы из различных локальных и удаленных репозиториев, не беспокоясь о разном времени загрузки этих ресурсов.

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

  1. Исполнено — действие Обещания выполнено успешно.
  2. Отклонено — действие обещания не выполнено
  3. В ожидании — действие Обещания еще не урегулировано

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

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

const promise = new Promise(function (resolve, reject){
   
   //Execute some code
  if (//Conditional to see whether to resolve or reject) {
     resolve("Working!")
   } else {
    reject(Error("Not working!"))
   }
}

В приведенном выше коде создается обещание, которое принимает функцию обратного вызова в качестве аргумента. Эта функция, в свою очередь, имеет два аргумента, resolve и reject, которые соответственно определяют возвращаемое значение в случае, если обещание было выполнено или отклонено. В этом случае экземпляр Promise, созданный выше, вернет «Working!» если он выполнен или ошибка с сообщением «Не работает!» если оно будет отклонено.

Итак, мы можем сделать с экземпляром обещания? Сцепите несколько функций!

promise.then(function(res){
   //Do some stuff if fulfilled
},
function(err){
   //Do some stuff if rejected
})

then — это метод экземпляра объектов Promise, который принимает до двух параметров: функцию, которая запускается в случае, если обещание было выполнено, и функцию, которая запускается в случае, если обещание было отклонено. В этом примере выполненное обещание будет передавать строку, устанавливающую res в «Работает!»; отклоненное обещание передаст ошибку, установив err в объект Error с сообщением «Не работает!» Затем каждая из функций может обрабатывать логику успеха или неудачи и возвращать значение. Если другой then связан, возвращаемое значение любой функции, которая была выполнена, будет передано в качестве аргумента следующему then, который связан с ним. И так далее!

Другой важный метод экземпляра промиса для работы с отклоненными промисами — это catch.

promise.catch(rejectionCallback(err))

По большей части catch — это просто синтаксический сахар для

promise.then(res => res, rejectionCallback(err))

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

// promise -> then(1 arg) -> catch
promise.then(resolveCallback(res)).catch(rejectionCallback)
// promise -> then(2 args)
promise.then(resolveCallback(res), rejectionCallback(err))

Обычно отклоненное промис пропускает все последующие вызовы then без второго аргумента (обратный вызов отклонения), пока не найдет либо а) then со вторым аргументом, либо б) вызов catch.

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

Предостережение с получением

До сих пор я работал с промисами только в контексте метода fetch. Если вы раньше работали с fetch, то знаете, что fetch возвращает Promise после отправки запроса и получения ответа. Следует учитывать, что fetch не будет отклоняться при получении ошибок ответа, таких как 404 или 500; fetch будет отклоняться только в том случае, если соединение с сервером прервано. Таким образом, обработка ошибок ответа не может выполняться вызовами catch, а вместо этого должна обрабатываться вызовами then. Это важное соображение при создании веб-приложений, особенно когда ваше приложение использует вызовы к другим серверам и API.

Источники





Собеседование по изучению JavaScript: что такое обещание?
«Собеседование по изучению JavaScript
 – это серия сообщений, предназначенных для подготовки кандидатов к ответам на распространенные вопросы, которые они задают… среда.com»