Или почему вам действительно нужно понимать обещания, прежде чем изучать async / await

Обещания были для меня одной из самых сложных вещей для понимания в JavaScript. Особенно после того, как мы узнали о кажущейся легкости и простоте async / await, цепочка обещаний быстро отошла на второй план, и о ней забыли. Однако после недавнего проекта хакатона я неожиданно застрял в асинхронном аду, я был вынужден заново познакомиться с методом работы с обещаниями, существовавшим до ES8, и благодаря ему я получил гораздо более глубокое понимание того, что такое обещания и как они работают. Это позволило мне не только использовать цепочку обещаний .then () (которую я раньше не использовал, потому что я не понимал ее и не осознавал ее ценность в мире с async / await), но также правильно использовать async / await и эффективно.

Цепочка обещаний и async / await позволяют нам дождаться завершения выполнения определенного кода перед запуском следующего бита. Это становится особенно необходимым, когда значение, возвращаемое таким действием, как вызов API, необходимо для последующей задачи. Метод async / await для работы с обещаниями привлекателен из-за его удобочитаемости по сравнению со старым стилем цепочки обещаний, но есть определенные опасности написания кода, который выглядит синхронным благодаря async / await без понимания базовой структуры. Одна из наиболее важных вещей, которые нужно понимать при использовании async / await, заключается в том, что асинхронная функция неявно возвращает обещание, и это обещание преобразуется в то, что возвращается из функции.

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

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

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

Один из моих любимых инструментов для отладки, console.log, в этой ситуации оказался очень вводящим в заблуждение. Я предполагал, что что-то работает должным образом, когда на самом деле это не так, потому что я смог выйти из системы с нужными мне данными после одного вызова API, но регистрация их в более поздней задаче привела к undefined. Однако консоль Chrome на самом деле дает вам подсказку, что задачи выполняются асинхронно - при наведении курсора на записанные данные отобразится всплывающее окно с сообщением «значение [было] вычислено только что». Это действительно помогло понять, что происходит, когда оказалось, что я могу получить доступ к нужным мне данным, но на самом деле они были возвращены только после того, как я уже попытался что-то с ними сделать.

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

Для дальнейшего чтения об обещаниях я нашел следующие статьи особенно полезными: