Если бы вы спросили меня неделю назад, могу ли я объяснить, что такое обещание JavaScript, я бы пообещал, что сделаю это. В конце концов, я много раз использовал промисы в нескольких приложениях, которые я создал, и с довольно большим успехом!

Однако мое понимание было подвергнуто испытанию во время собеседования по кодированию, когда я обнаружил, что изо всех сил пытаюсь сформулировать концепцию. Я хотел собрать краткое объяснение здесь, чтобы изложить вещи более ясно.

Что такое обещание в JavaScript?

Обещание — это объект, который является представлением или заполнителем для результата асинхронной функции. К обещанию можно прикрепить обратные вызовы для обработки выполненного значения обещания или причины отклонения. Объект Promise был новой функцией ES6.

Почему обещания?

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

По моему опыту, я в основном использовал промисы и методы обратного вызова промисов при использовании .fetch(). Подробнее об этих обратных вызовах чуть позже.

Три этапа обещания

  1. В ожидании: обещание еще не выполнено или отклонено.
  2. Решено: обещание выполнено!
  3. Отклонено: произошла ошибка, и обещание не было разрешено.

Обещай.тогда()

Обратный вызов then сработает, когда обещание будет выполнено. Когда промис завершает свою работу, он запускает .resolve() (это происходит за кулисами), а затем приходит .then().

promise.then(function() { 
    // do something with the result
})

Обещание.поймать()

Catch используется для обработки ошибок. Возможно, например, произошла ошибка сервера или файл, к которому вы пытаетесь получить доступ, не существует. Обратный вызов catch может использоваться для обработки этих исключений.

promise.then(function() { 
    // do something with the result
}).catch(function() {
   // send an error
})

Обещание.наконец-то()

Наконец вызывается, когда обещание выполнено, независимо от того, было ли оно выполнено или отклонено. Вы можете использовать finally, чтобы избежать дублирования кода в .then() и .catch().

promise.finally(function() {
   // handle the result of the resolved or rejected promise
})

Использование промисов с .fetch()

Как я упоминал ранее, я много раз использовал обратные вызовы обещаний при использовании .fetch(). Вот упрощенный пример того, как это может работать.

fetch(url)
  .then(processData)
  .then(saveData)
  .catch(handleErrors)

Вы выбираете URL-адрес конечной точки API, затем обрабатываете и сохраняете данные, а также отлавливаете и обрабатываете ошибки, если это необходимо. Ниже приведен более конкретный пример из проекта, над которым я работал.

class Api {
  constructor() {
  this.baseURL = 'https://jsonplaceholder.typicode.com';
}
updateUserId(albumId, bodyData) {
    return fetch(`${this.baseURL}/albums/${albumId}`, {
      method: 'PUT',
      body: JSON.stringify({ bodyData }),
      headers: {
        "Content-type": "application/json; charset=UTF-8"
      }
    })
      .then(res => res.json())
      .then(function(data) {
        renderData(data);
      })
      .catch(function(error) {
        console.log('Fetch Error :-S', error);
      });
    }
}

Результат запроса на выборку — это то, что было обещано. Как только обещание выполнено, данные преобразуются в формат JSON. Затем я отправляю эти данные в свою функцию renderData(). Я добавил ошибку в свой .catch() на случай, если что-то пойдет не так.

И это мое объяснение обещания, как и было обещано.