В этом видео мы с вами разберем async await из es7 и сравним, чем он лучше промисов.
Сразу же напомню, что из коробки он поддерживается только в последних версиях браузеров, поэтому, если вы хотите поддерживать и старые браузеры тоже, то используете babel для транспайла кода в es5.
Что же такое async await? Это новый стиль написания асинхронного кода. До async await мы использовали промисы, а еще раньше коллбеки. Но, на самом деле, async await написан сверху промисом и хорошо с ними работает.
Зачем его вообще использовать? Async await заставляет код, который работает асинхронно, выглядеть, как синхронный код. Это именно то, ради чего его используют.
Давайте разберем примеры.
const fetchProducts = () => Promise.resolve({data: [1,2,3]})
const getProducts = () => {
fetchProducts().then(data => {
console.log('data', data)
})
}
getProducts()
У нас есть функция fetchProducts, которая возвращает Promise. И функция getProducts, в которой мы ее вызываем.
Если мы посмотрим в браузер, то все работает.
Давайте попробуем этот код переписать на async/await.
const getProducts = async () => {
console.log('data', await fetchProducts())
}
Мы просто добавляем слово async перед скобками функции, показывая, что мы хотим работать с asyn/await и внутри в месте, где мы выполняем асинхронную операцию мы пишем await и промис.
Если мы посмотрим в браузер, то все работает.
Сразу скажу, что если вы не поставили функции async, то вы не сможете использовать внутри await.
Также, как только мы написали async, то функция сразу стала возвращать promise.
console.log(getProducts())
Как мы видим в браузере, у нас вывелся промис и мы можем в любом другом месте на этот промис подписаться.
Почему код с async await лучше? Первое: потому что он короче. Второе: потому что у нас код становится плоским, что упрощает поддержку. Третье: нам намного легче избегать callback hell, когда наш код плоский.
Теперь, давайте посмотрим как хендлить ерроры в async await.
В промисах мы обычно использовали catch.
const fetchProducts = () => Promise.reject('someErr happened')
const getProducts = () => {
fetchProducts().then(data => {
console.log('data', data)
}).catch (err => {
console.log('err', err)
})
}
getProducts()
Для того, чтобы отлавливать ошибки с async await, нам нужно заворачивать весь блок кода в try catch.
const getProducts = async () => {
try {
console.log('data', await fetchProducts())
} catch (err) {
console.log('err', err)
}
}
Ну и напоследок, давайте сравним код с промисами и с async await с небольшим callback hell.
const fetchProducts = () => Promise.resolve({data: [1,2,3]})
const fetchAdditional = (products) => Promise.resolve({data: [2,4,5]})
const getProducts = () => {
return fetchProducts().then(products => {
if (products.data.length) {
return fetchAdditional(products.data)
.then(additionalData => {
return additionalData
})
} else {
return products.data
}
})
}
getProducts().then(result => {
console.log('result', result)
})
У нас есть 2 функции fetchProducts и fetchAdditional. В getProducts мы хотим, после получения продуктов, если массив не пустой, сфетчить дополнительные данные. Этот код уже начинает напоминать callback hell.
Давайте перепишем его на async/await.
const getProducts = async () => {
const products = await fetchProducts()
if (!products.data.length) {
return products.data
}
return await fetchAdditional(products.data)
}
Я думаю теперь плюсы async await стали окончательно очевидны.
Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.