LanguageRussian

JavaScript: учим Promises

Promises в JavaScript – это проще, чем вы думаете. Основы Promises.

Promises

Что нового я узнаю?

Данная статья посвящена promises (промисам) в JavaScript. Она не является исчерпывающим руководством, однако в ней представлена информация, которая поможет вам разобраться с основными моментами, необходимыми для начала использования промисов в вашем коде.

Зачем нужны промисы в JavaScript?

С помощью промисов (как, собственно, и callback-функций) одна часть кода выполняется только после того, как была выполнена другая часть.

Зачем вообще нужны промисы? Все очень просто: представьте веб-сайт, который сначала загружает данные от API, затем он обрабатывает полученные данные, форматирует их и отображает пользователю. Так вот, если мы попытаемся обработать и отформатировать такие данные до того как API выберет необходимую информацию, то мы либо получим сообщение об ошибке, либо перед нами откроется пустая веб-страница. Использование промисов гарантирует, что данные, полученные из API, не будут обрабатываться/форматироваться до тех пор, пока вызов API не будет успешно выполнен.

Что такое промисы?

В JavaScript «промисы» представляет собой конечный результат выполнения асинхронной операции. Их можно рассматривать в качестве своеобразного «заполнителя». Такой «заполнитель», по существу, является объектом, к которому мы можем привязать функции обратного вызова (колбэки).

Всего существует 3 возможных состояния для промисов:

  • Pending (ожидание) означает, что асинхронная операция выполняется;
  • Fulfilled (успешное выполнение) означает, что операция была выполнена успешно, а промисам было присвоено определенное значение;
  • Rejected (выполнено с ошибкой) означает, что во время выполнения операции произошла ошибка.

В том случае если состояние промиса не находится в ожидании обработки (pending), то промис считается выполненным, при чем выполненным окончательно: его состояние не может меняться.

Начало работы с промисами

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

Например, простой промис может выглядеть подобным образом:

Из приведенного выше примера видно, что сначала мы вызываем функцию runFunction (). Ввиду того, что runFunction() возвращает промис, то он (промис) будет выполнен только после  того, как одна из возможных функций – либо successFunc, либо failureFunc – будет выполнена. Если же промис был выполнен успешно (fulfilled), то вызывается sucessFunc, а если во время выполнения такого промиса произошла ошибка – вызывается failureFunc.

Пример использования промисов

Давайте рассмотрим на примере, где мы можем использовать наши промисы. Ничего страшного, если сейчас вам покажется, что такой пример не имеет смысла: позже вы все поймете.

Вверху представлены две функции: delay() и logHi(). Функция logHi()  просто выводит на консоль строку ‘hi’. С функцией delay() все немного сложнее: она возвращает промис, выполнение которого будет разрешено после заданного времени. Для регистрации обратных вызовов (колбэков) мы используем метод then (), чтобы получить одно из возможных значений – либо fulfilled, либо rejected.

Учитывая все вышеописанное, в нашей функции запаздывания мы можем применить delay(2000).then(logHi), при этом после 2 секунд (2000 миллисекунд) выполнение нашего промиса будет разрешено и только после этого функция logHi  будет выполнена.

Чтобы лучше понять, как это работает, просто откройте Google Chrome Developer Tools и напишите подобный код!

Чейнинг или цепочки из промисов

Одно из основных преимуществ промисов заключается в том, что мы можем строить цепочки или «чейны» из асинхронных операций. Это значит, что мы можем указать, что выполнение последующих операций будет начато только после успешного выполнения предыдущих операций. Такой метод называется чейнинг (от англ. chaining) промисов. Привожу пример:

В приведенном выше примере кода показано, что изначальный промис будет выполнен по прошествии 2000 миллисекунд, при этом его значение будет равно 1. После этого вызывается  then(), а значение “1” выводится на экран. Наконец, первоначальное значение добавляется к значению, равному “2”, и в итоге на экран выводится новое значение – 3. После этого полученное значение переходит к следующему обработчику then(), и весь процесс начинается сызнова.

Как вы уже поняли данный пример навряд ли будет полезен в реальных проектах, однако с его помощью вы лучше поймете принцип объединения промисов в чейны. Такой подход может оказаться очень полезным для определенных задач, выполняемых в JavaScript, например: для загрузки внешних ресурсов или для ожидания данных API перед их обработкой.

Устранение ошибок

Пока что мы с вами рассмотрели только выполнение промисов, однако это не все, что мне хотелось бы вам рассказать. Например, мы можем использовать .catch() для выявления ошибок, которые произошли в цепочке промисов. Давайте рассмотрим, что собой представляет .catch():

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

После выполнения данного кода произойдет следующее:

  • Промис будет выполнен спустя 2 секунды и примет значение “1”.
  • Полученное значение перейдет к следующему .then()и будет выведено на экран. Значение “2” будет добавлено к первому значению, в результате чего мы получим новое значение – “3”, которое перейдет ко второму.then()
  • Будет выявлена ошибка. Выполнение кода будет приостановлено, а промис примет значение «rejected».
  • .catch() получит сообщение о найденной ошибке в значении, и на экране появится соответствующее сообщение.

Выглядеть это будет следующим образом:

Promises2

Заключение:

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

Оригинал.

 

Avatar
About author

I, Dr. Michael J. Garbade is the co-founder of the Education Ecosystem (aka LiveEdu), ex-Amazon, GE, Rebate Networks, Y-combinator. Python, Django, and DevOps Engineer. Serial Entrepreneur. Experienced in raising venture funding. I speak English and German as mother tongues. I have a Masters in Business Administration and Physics, and a Ph.D. in Venture Capital Financing. Currently, I am the Project Lead on the community project -Nationalcoronalvirus Hotline I write subject matter expert technical and business articles in leading blogs like Opensource.com, Dzone.com, Cybrary, Businessinsider, Entrepreneur.com, TechinAsia, Coindesk, and Cointelegraph. I am a frequent speaker and panelist at tech and blockchain conferences around the globe. I serve as a start-up mentor at Axel Springer Accelerator, NY Edtech Accelerator, Seedstars, and Learnlaunch Accelerator. I love hackathons and often serve as a technical judge on hackathon panels.