Когда я сталкиваюсь с новым абстрактным понятием в программировании, я всегда пытаюсь связать его с чем-то простым и вполне понятным, например с едой 😋
Я ОБОЖАЮ еду! и почти все, кого я встречал, делают. Вот почему сегодня мы будем думать об обещаниях и выполнении асинхронного кода в JavaScript как о вкусных блюдах. Я пробовал это со своими учениками в RBK, и это сработало отлично. Вот почему я собираюсь связать выполнение асинхронного кода с заказом еды в ресторане. А теперь давайте закажем несколько обещаний.
Обещания и еда
Время обеда, ты голоден. Вы не умеете готовить, и у вас даже нет времени готовить. Вот почему вы решили пообедать в ресторане McDonald за углом. Вам всегда нравились чизбургеры, которые они делают, поэтому ваше решение было совсем несложным.
Вы идете к кассиру и просите у него чизбургер. Вы платите за еду, и взамен он возвращает вам билет. Теперь этот билет - это обещание JavaScript. Это не еда, это не ценность, а будущая ценность. Кассир (или официант) пообещал, что вернет вам еду. Когда? это может занять несколько секунд или минут, как это может занять час. Все зависит от того, насколько быстрые плиты и сколько людей уже ждут в очереди. В худшем случае к вам подойдет официант и скажет, что у них закончился сыр 😫 Может, тогда вы закажете что-нибудь еще.
То же самое и с обещаниями: вы выполняете асинхронный код (например, отправляете запрос на сервер со стороны клиента) и ждете своего ответа. Между тем, вы получите взамен обещание будущих данных.
Когда бургер (или данные), наконец, готов, вы можете затем начать есть его и наслаждаться вкусом. В противном случае вы можете заказать что-нибудь еще или посетить другой ресторан, в котором еще есть сыр.
То же самое и с обещаниями. Если вы вернете свой ответ, вы можете манипулировать этими данными или вывести их пользователю. С другой стороны, если вы этого не сделаете, вы сделаете что-то еще, например, проинформируете пользователя, что данных не осталось.
Использование обещаний для отправки запроса к API
Теперь давайте посмотрим на пример в коде. В этом блоге я собираюсь отправить запрос GET в Github API. Однако API не отправляет еду обратно. Тем не менее, Github API может отправить нам еще одну удивительную вещь, которая может быть лучше еды! Да, вы догадались… EMOJIS 🎉 🎉 Приступим!
Первым делом, конечно же, нужно создать файл JavaScript. Я назову его index.js. Затем нам понадобится токен API из Github, чтобы иметь возможность отправлять запросы. Вы можете создать свой собственный на https://github.com/settings/tokens.
Я собираюсь поместить свой собственный ключ в отдельный файл, а затем импортировать его в index.js и использовать npm для установки Axios.
Я импортировал Axios, чтобы использовать его для отправки http-запроса к API. Это отличная клиентская HTTP-библиотека, основанная на обещаниях. В этом блоге я не буду углубляться в то, как создать и заставить функцию возвращать обещание, используя родные обещания или внешние библиотеки, такие как Bluebird. Вместо этого я сосредоточусь на том, как отправлять запросы и обрабатывать возвращаемые значения в шаблоне на основе обещаний.
Теперь давайте закажем еду (смайлики) 😅
Для этого я создаю функцию под названием getEmojis и вызываю ее в строке 21. Если мы углубимся в определение функции, мы обнаружим, что в строке 5 мы делаем запрос на получение с Axios с методом get. Этот метод принимает два аргумента: путь «https://api.github.com/emojis» и объект, содержащий свойство headers, где мы предоставили импортированный API_TOKEN как значение Авторизация.
Этот вызов теперь не возвращает значение сразу (так как мы не сразу получаем чизбургер). Вместо этого он возвращает обещание будущему значению. В конце концов, получение ответа от удаленного сервера требует времени, как и шеф-повару, чтобы приготовить бургер.
Возвращаемое значение типа Promise имеет два разных важных метода: .then () и catch (). Первый будет вызван, когда запрос был успешным (вернул обещанное значение), а второй будет вызываться, когда запрос не удастся (не вернул обещанное значение). Теперь запрос может завершиться неудачно по многим причинам, включая, помимо прочего, потерю доступа к сети или то, что мы отправили его по несуществующему пути (например, «https://api.github.com/food», поскольку Github API пока не дает еды).
Итак, API сообщает, что когда мы отправляем запрос GET на эту конечную точку, он отправляет нам обратно полный список смайлов, которые обрабатывает GitHub. Вот почему я предполагаю, что моя функция обратного вызова, которая будет выполнена, будет иметь один аргумент - массив эмодзи. В этом примере я просто запишу их в консоль. В другом контексте, когда ваш бургер будет готов и подан, вы выполните функцию eatBurger с аргументом (бургер).
Если запрос не выполняется, я перехватываю возвращаемое мне сообщение об ошибке и отправляю его, чтобы иметь возможность отладить свой код.
Заключение
Обещания были отличным дополнением к JavaScript. Они позволили нам иметь довольно читаемый код и избавили нас от ада обратных вызовов, когда вы выполняете один обратный вызов внутри другого. Фактически, в обратных вызовах наш код становится все более и более горизонтальным, в то время как с обещаниями он упорядочивается вертикально, что делает его читабельным для разработчиков и homo sapiens в целом.
У значения обещания, которое мы получаем взамен, есть два основных метода: .then (), который выполняется в случае успеха, и .catch (), который выполняется в случае неудачи.