Асинхронный JavaScript: как работают колбеки, промисы и async-await
JavaScript позиционирует асинхронное программирование как фичу. Это означает, что если какое-либо действие занимает некоторое время, ваша программа может продолжать выполнять другие действия, пока предыдущее действие завершается. Как только это действие выполнено, ты можешь что-то сделать с результатом. Это будет отличным решением для таких функций, как выборка данных, но это может сбить с толку новичков. В JavaScript у нас есть несколько различных способов справиться с асинхронностью: колбеки, промисы и async-await.
Колбек функции
Функция колбек - это предоставляемая вами функция, которая будет выполняться после завершения асинхронной операции. Давай создадим фейковую функцию для получения пользовательских данных и используем колбек, чтобы что-то сделать с результатом.
Фейковая функция получения данных
Сначала мы создаем фейковуя функция получения данных, которая не принимает колбек. Поскольку fakeData не существует в течение 300 миллисекунд, у нас нет синхронного доступа к ней.
Чтобы действительно иметь возможность что-то делать с нашими fakeData, мы можем передать fetchData как ссылку на функцию, которая будет обрабатывать наши данные!
Давайт создадим базовую функцию колбек и протестируем ее:
Через 300 мс мы увидим следующее:
Промисы
Объект Promise представляет возможное завершение операции в JavaScript. Промисы могут быть либо resolve, либо reject (решены или отклонены). Когда Promise разрешается (resolve()), ты можешь обработать его возвращенное значение с помощью метода then. Если Promise отклонено (reject()), ты можешь использовать catch для отлова ошибки и обработать её.
Синтаксис объекта Promise следующий:
Если fn - это функция, которая принимает функцию resolve и, необязательно, функцию reject.
Функция получения данных (с промисами)
Давай использовать ту же функцию получения данных, что и раньше. Вместо того, чтобы передавать колбек, мы собираемся вернуть новый объект Promise, который разрешится resolve() с данными нашего пользователя через 300 мс. В качестве бонуса мы также можем дать ему небольшой шанс отказаться reject().
Наша новая функция fetchData может использоваться следующим образом:
Если fetchData успешно разрешается (resolve()) (это будет происходить 90% времени), мы будем регистрировать наши пользовательские данные, как мы это делали с колбеком. Если он будет отклонен (reject()), мы получим console.error сообщение об ошибке, которое мы создали (“Fetch failed!“).
Одна из плюшек промисов - это то, что вы можете создать цепочку промисов, чтобы выполнить последующие промисы. Например, мы могли бы сделать что-то вроде этого:
Кроме того, мы можем передать массив промисов в Promise.all, чтобы принять меры только после того, как все промисы разрешены (resolve()),то есть все данные получены:
В этом случае, если оба промиса успешно разрешены (resolve()), будет выведено следующее:
async-await
Async-await предлагает другой синтаксис для написания промисов, которые некоторые считают более понятным. С помощью async-await ты можешь создать асинхронную функцию. Внутри этой асинхронной функции ты можешь дождаться результата Promise перед выполнением следующего кода! Давай посмотрим на наш пример получения данных.
Не плохо, правда? Один маленький ньюансик: мы не рассматриваем наш случай отказа от Promise. Мы можем сделать это с помощью try / catch.
Надеюсь тебе было полезно😁