Промис в JavaScript — это заменитель (прокси) для значения текущей операции. Обычно мы используем промис для управления ситуациями, когда необходимо дождаться результата операции. Например, при загрузке файлов на сервер и ожидании ответа от API, или просто при запросе у пользователя выбора файла с их компьютера.
В этой статье вы узнаете о промисах в JavaScript, создавая реальное приложение, похожее на приведенное ниже:
Что такое промис?
Промис — это просто функция, она возвращает объект, к которому можно прикрепить обратные вызовы.
Обратные вызовы, прикрепленные к объекту промиса, будут вызываться только после завершения операции. Обратные вызовы будут ожидать, пока операция не будет выполнена или отклонена.
|
Прежде чем промис окончательно решится (то есть либо выполнится, либо будет отклонен), он должен пройти через разные состояния:
Состояние |
Описание |
Обратный вызов |
Ожидание |
Операция все еще выполняется, и промис находится в ожидании |
- |
Выполнен |
Операция завершена успешно |
.then() |
Отклонен |
Операция завершена с ошибкой |
.catch() |
Завершен |
Промис либо разрешен, либо отклонен, в любом случае вызывается этот обратный вызов |
.finally() |
Когда создается промис, начальное состояние — ожидание. Затем, в зависимости от результата операции, промис либо выполняется, либо отклоняется.
Из таблицы выше можно легко увидеть обратный вызов, который будет вызван в зависимости от состояния промиса:
|
Как использовать промисы в JavaScript
Теперь, когда вы узнали, что такое промис, давайте покажем, как вы можете использовать промисы в JavaScript, создав приложение для поиска фильмов, которое мы видели ранее.
Базовое приложение для поиска фильмов должно иметь поле ввода, где пользователи могут искать свои любимые фильмы. Также должно быть пользовательский интерфейс для отображения базовой информации о найденном фильме.
Давайте начнем с создания HTML.
Как написать HTML
Для целей этого руководства и чтобы показать живые примеры, я буду использовать Codepen, но вы можете использовать ваш любимый редактор кода.
Создайте файл index.html и добавьте следующий код:
|
Мы создали скелет нашего приложения для фильмов. Теперь давайте оживим его с помощью CSS:
|
Как получить фильм
Чтобы получить наш фильм, мы будем использовать API TVMAZE. Создайте файл main.js и добавьте следующий код:
|
Мы создали функцию get_movie(value = "Game of thrones"), которая использует API fetch в JavaScript. Мы используем его для выполнения GET запроса к нашему API фильмов.
API fetch возвращает промис. Чтобы использовать ответ от API, мы прикрепляем обратный вызов .then(), в который передаем response.json() в новую функцию create_UI(). Давайте создадим функцию create_UI:
|
Эта функция, как следует из названия, помогает нам создать пользовательский интерфейс для нашего приложения фильмов. Но нам все еще нужен способ получить имя фильма от пользователей, так что давайте это исправим.
Первое, что нам нужно сделать, это добавить обработчик события onsubmit в нашу HTML-форму:
|
Теперь в нашем файле main.js мы можем обработать то, что происходит при отправке формы:
|
Каждый раз, когда пользователь отправляет форму, мы получаем значение, которое они ввели в поле поиска, и передаем его в функцию get_movie(value = "Game of thrones"), которую мы создали ранее.
Цепочка промисов
В отличие от того, что мы видели в предыдущих примерах, обратный вызов .then() не является концом. Дело в том, что когда вы возвращаете значение промиса, вы получаете другой промис. Это становится очень полезным, когда вы хотите выполнить серию асинхронных операций по порядку.
Например, наше API фильмов не только возвращает информацию о фильме, но и информацию обо всех эпизодах. Допустим, что мы действительно не хотим отображать все эпизоды "Игры престолов", нам нужны только первые четыре (4) эпизода.
С помощью цепочки промисов мы можем легко этого достичь:
|
Это все та же функция get_movie(), но на этот раз, вместо того чтобы передавать данные в функцию create_UI, мы возвращаем ответ .then((response) => response.json()). Это создает новый промис, к которому мы можем прикрепить дополнительные обратные вызовы.
В идеале эта цепочка может продолжаться бесконечно. Помните, что все, что вам нужно сделать, это вернуть значение промиса.
Как обрабатывать ошибки в промисах
Ошибки, которые происходят в промисе, немедленно попадают в обратный вызов .catch():
|
Обратный вызов .catch() является сокращением для .then(null, (error) => {}). Вы также можете написать это так:
|
В нашем приложении для поиска фильмов, например, когда мы сталкиваемся с ошибками, мы можем обработать и отобразить пользователям приятное сообщение об ошибке в обратном вызове .catch():
|
Теперь, если по какой-то причине мы получаем ошибку, обратный вызов .catch() будет вызван, и мы отобразим корректную ошибку пользователю.
Как создать промисы в JavaScript
Теперь, когда мы узнали, что такое промисы и как их использовать, давайте посмотрим, как мы можем создать промис в JavaScript.
Чтобы создать промис в JavaScript, используйте конструктор промиса. Конструктор принимает один аргумент: функцию с двумя параметрами, resolve и reject:
|
Затем мы можем использовать наш new_promise, прикрепляя к нему обратные вызовы:
|
Подведем итоги
В этом руководстве мы узнали о промисах, что это такое и как их использовать, создавая приложение для поиска.
Счастливого кодинга!