JavaScript с использованием async и await
WebDEVAsync функции представляют собой комбинацию promise и генераторов, и в основном они представляют собой абстракцию более высокого уровня над promise. Позвольте мне повторить: async/await построен на promise.

Почему был введён async/await
Когда Promises были введены в ES2015, они должны были решить проблему с асинхронным кодом, и у них это удалось, но на протяжении двух лет, которые разделяли ES2015 и ES2017, было ясно, что promises не могут быть окончательным решением задачи.
Promises были введены для решения известной проблемы callback hell, но тогда они сами породили новую сложность и сложный синтаксис.
Promises были хорошими примитивами, вокруг которых мог быть раскрыт лучший синтаксис для разработчиков, поэтому, когда подошло время, мы получили async функции.
Async/await делает код похожим на синхронный, но он асинхронен и не блокируется компилятором.
Как это работает
Async функция возвращает promise, как на этом примере:
const doSomethingAsync = () => {
return new Promise((resolve) => {
setTimeout(() => resolve('I did something'), 3000)
})
}
Когда вы вызываете эту функцию, вы ждёте (await), и вызов останавливается до тех пор, пока promise не будет разрешён или отклонён. Один нюанс: клиентская функция должна быть определена как async. Вот пример:
const doSomething = async () => {
console.log(await doSomethingAsync())
}
Быстрый пример
Это простой пример async/await, используемый для запуска функции асинхронно:
const doSomethingAsync = () => {
return new Promise((resolve) => {
setTimeout(() => resolve('I did something'), 3000)
})
}
const doSomething = async () => {
console.log(await doSomethingAsync())
}
console.log('Before')
doSomething()
console.log('After')
Указанный выше код выведет в консоль браузера следующее:
Before
After
I did something //after 3s
Любая функция может вернуть promise
Добавление ключевого слова async в любую функцию означает, что функция обязательно вернёт promise.
Даже если это явно не так, компилятор заставит функцию сделать это.
Вот почему этот код будет работать:
const aFunction = async () => {
return 'test'
}
aFunction().then(alert) // This will alert 'test'
это то же самое, что:
const aFunction = async () => {
return Promise.resolve('test')
}
aFunction().then(alert) // This will alert 'test'
Код намного проще читать
Как вы можете видеть в приведённом выше примере, наш код выглядит очень просто. Сравните его с кодом, в котором используются простые promise или callback.
Приведённый выше пример очень простой, основные преимущества будут видны, когда код станет намного сложнее.
Для примера, мы получим ресурс JSON и проанализируем его, используя promise:
const getFirstUserData = () => {
return fetch('/users.json') // получить список users
.then(response => response.json()) // parse JSON
.then(users => users[0]) // выбрать первого user
.then(user => fetch(`/users/${user.name}`)) // получить информацию о user
.then(userResponse => response.json()) // parse JSON
}
getFirstUserData()
И сделаем то же самое, но уже при помощи async/await:
const getFirstUserData = async () => {
const response = await fetch('/users.json') // получить список users
const users = await response.json() // parse JSON
const user = users[0] // выбрать первого user
const userResponse = await fetch(`/users/${user.name}`) // получить информацию о user
const userData = await user.json() // parse JSON
return userData
}
getFirstUserData()
Несколько async функций последовательно
Написать async функцию очень легко, и её синтаксис гораздо читабельнее, чем у обычного promise:
const promiseToDoSomething = () => {
return new Promise(resolve => {
setTimeout(() => resolve('I did something'), 10000)
})
}
const watchOverSomeoneDoingSomething = async () => {
const something = await promiseToDoSomething()
return something + ' and I watched'
}
const watchOverSomeoneWatchingSomeoneDoingSomething = async () => {
const something = await watchOverSomeoneDoingSomething()
return something + ' and I watched as well'
}
watchOverSomeoneWatchingSomeoneDoingSomething().then((res) => {
console.log(res)
})
Будет выведено:
I did something and I watched and I watched as well
Лёгкая отладка
Отладка promise может вызвать затруднение, потому что отладчик не будет переходить на асинхронный код.
С async/await сделать это гораздо проще, потому что для компилятора эти функции похожи на синхронный код.