Узнайте, как можно использовать обещания JavaScript в своих приложениях для обработки асинхронного кода.

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

«Управление сложностью - это суть компьютерного программирования». - Брайан Керниган

Как сказал Брайан, умение управлять сложными ситуациями как разработчик - вот что такое программирование. Чтобы стать великими разработчиками, мы должны ознакомиться со сложными концепциями, такими как эта.

В этой статье мы рассмотрим, что такое обещания и почему мы должны их использовать. Мы также рассмотрим, почему так важно объединение обещаний, и даже увидим, как метод Promise.all() может помочь нам объединить несколько обещаний в одно.

Поехали!

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

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

Их не следует путать с async/await.

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

Здесь у нас есть пример киоска с билетами в кино, который использует обратные вызовы для обработки нашего асинхронного кода. И selectMovie(), и getMovieTicket() передают два обратных вызова в качестве аргументов. Первый вызывается в случае успешной транзакции, а второй - в случае неудачи.

Поскольку и selectMovie(), и getMovieTicket() являются асинхронными функциями, мы используем обратные вызовы, чтобы отложить выполнение других строк кода до завершения процесса.

Чтобы этот пример работал правильно, нам нужно убедиться, что наши функции выполняются в правильном порядке, иначе мы получим неправильный результат. Это очень частое явление при работе с асинхронным кодом.

Теперь давайте перепишем приведенный выше пример с помощью обещаний, чтобы увидеть, что изменилось.

Как видно из приведенного выше кода, он не сильно отличается от нашей предыдущей реализации. Вместо того, чтобы передавать обратные вызовы нашим функциям, как раньше, мы возвращаем обещание. Это позволяет нам прикреплять обратные вызовы к концу нашего обещания с помощью методов then() и catch().

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

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

Давайте подробнее рассмотрим, как работают оба этих метода.

Promise.then ()

Метод then() возвращает обещание. Если наше обещание выполняется, then() вызывает функцию, которая возвращает выполненное значение. В нашем случае это значение, которое мы передаем обратному вызову resolve() в нашем примере выше.

Promise.catch ()

Как и метод then(), catch() также возвращает обещание, но только тогда, когда наше обещание отклонено. Этот метод может показаться вам знакомым, если вы когда-либо использовали try-catch блок. Если наше обещание отклоняется, catch() вызывает функцию, которая возвращает причину невыполнения нашего обещания.

Мы можем увидеть это в действии, посмотрев на пример ниже.

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

Что, если мы хотим распечатать квитанцию ​​после обработки нашего платежа?

Давайте посмотрим, как мы сможем добиться этого, связав свои обещания.

Цепочка обещаний

Связать обещания так же просто, как и они приходят. Если мы хотим зарегистрировать квитанцию ​​после обработки платежа, мы можем просто сделать это, добавив еще один then() метод в конец предыдущего.

Мы можем увидеть, как это работает, наблюдая за приведенным ниже кодом.

Чтобы это работало правильно, нам нужно убедиться, что мы возвращаем значение из первого then(), иначе наш второй метод вернет undefined. Мы можем связать столько из них, сколько захотим.

Небеса - предел!

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

Давай сделаем это сейчас.

В приведенном выше фрагменте мы проверяем, завершает ли принтер статус OK, прежде чем выполнить наше обещание. Если принтер обнаруживает ошибку, мы отправляем отклоненное обещание и записываем ошибку в консоль.

Если мы добавим это к другим обещаниям, мы получим что-то вроде этого.

Не знаю, как вы, но с точки зрения читабельности это выглядит хуже.

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

Так как же это исправить?

Конечно, через цепочку!

Когда вы столкнетесь с такой ситуацией, вам действительно пригодится цепочка. Итак, давайте посмотрим, как цепочка решает нашу проблему.

Это выглядит намного лучше!

Мы не только удалили несколько строк кода, но и сделали его более читабельным. Уверен, наши коллеги-программисты нас за это поблагодарят.

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

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

Как использовать Promise.all ()

Если вы заметили в примерах выше, и selectMovie(), и getMovieTicket() не зависят от результата другого обещания. Эти методы являются хорошими кандидатами, когда дело доходит до использования Promise.all() метода.

Что такое Promise.all ()?

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

Давайте рассмотрим пример, чтобы мы могли лучше понять этот метод.

Promise.all() принимает на вход все три наших обещания. Как только все обещания выполнены, мы деструктурируем полученный массив значений и регистрируем наш вывод.

Поначалу это может показаться устрашающим, но я обещаю, что это проще, чем вы думаете.

Теперь, когда у нас есть некоторое представление о том, как работает этот метод, давайте попробуем реализовать его в существующем коде билета в кино, который использовался ранее.

Вуаля!

Используя метод Promise.all(), наш код становится намного чище и позволяет сэкономить несколько строк кода. И посмотри! Мы также можем использовать для этого цепочку. Как удобно.

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

И с этим, я думаю, теперь у вас есть возможность справиться с асинхронными обещаниями с помощью JavaScript.

Заключение

Мы только что увидели, как обещания JavaScript могут помочь сделать наш код чистым и читаемым, а также решить общие проблемы, такие как ад обратного вызова.

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

Использование Promise.all() для объединения нескольких обещаний в одно может помочь еще больше урезать наш код, и мы также можем добавить его в существующий код, который использует цепочку.

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

Спасибо за чтение.