- Вступление
- Почему были введены async/await?
- Как это работает
- Краткий пример
- Обещай все то, что
- Код намного проще для чтения
- Несколько асинхронных функций последовательно
- Более простая отладка
Вступление
JavaScript эволюционировал за очень короткое время от обратных вызовов до обещаний (ES2015), и с ES2017 асинхронный JavaScript стал еще проще с синтаксисом async/await.
Асинхронные функции представляют собой комбинацию обещаний и генераторов , и в основном они представляют собой абстракцию более высокого уровня по сравнению с обещаниями. Позвольте мне повторить: async/await построен на обещаниях .
Почему были введены async/await?
Они уменьшают шаблонность вокруг обещаний и ограничение “не разрывайте цепь”, связывающее обещания.
Когда в ES2015 были введены обещания, они предназначались для решения проблемы с асинхронным кодом, и они это сделали, но за 2 года, разделявшие ES2015 и ES2017, стало ясно, что обещания не могут быть окончательным решением .
Обещания были введены для решения знаменитой проблемы ад обратного вызова , но они сами по себе усложнили и усложнили синтаксис.
Это были хорошие примитивы, вокруг которых разработчики могли бы использовать лучший синтаксис, поэтому, когда пришло время, мы получили асинхронные функции .
Они заставляют код выглядеть синхронным, но он асинхронен и не блокируется за кулисами.
Как это работает
Асинхронная функция возвращает обещание, как в этом примере:
const doSomethingAsync = () => {
return new Promise(resolve => {
setTimeout(() => resolve('I did something'), 3000)
})
}Когда вы хотите позвонить эта функция, которую вы добавляете ожидание и вызывающий код остановится до тех пор, пока обещание не будет выполнено или отклонено . Одно предостережение: клиентская функция должна быть определена как асинхронная . Вот пример:
const doSomething = async () => {
console.log(await doSomethingAsync())
}Краткий пример
Это простой пример асинхронности/ожидания, используемый для асинхронного запуска функции:
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
Обещай все то, что
Добавление ключевого слова async к любой функции означает, что функция вернет обещание.
Даже если он не делает этого явно, он внутренне заставит его вернуть обещание.
Вот почему этот код действителен:
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'
Код намного проще для чтения
Как вы можете видеть в приведенном выше примере, наш код выглядит очень простым. Сравните его с кодом, использующим простые обещания, с функциями цепочки и обратного вызова.
И это очень простой пример, основные преимущества возникнут, когда код будет намного сложнее.
Например, вот как вы могли бы получить ресурс JSON и проанализировать его, используя обещания:
const getFirstUserData = () => {
return fetch('/users.json') // get users list
.then(response => response.json()) // parse JSON
.then(users => users[0]) // pick first user
.then(user => fetch(`/users/${user.name}`)) // get user data
.then(userResponse => userResponse.json()) // parse JSON
}
getFirstUserData()И вот та же функциональность, предоставляемая с помощью await/async:
const getFirstUserData = async () => {
const response = await fetch('/users.json') // get users list
const users = await response.json() // parse JSON
const user = users[0] // pick first user
const userResponse = await fetch(`/users/${user.name}`) // get user data
const userData = await userResponse.json() // parse JSON
return userData
}
getFirstUserData()Несколько асинхронных функций последовательно
Асинхронные функции могут быть объединены в цепочку очень легко, а синтаксис гораздо более удобочитаем, чем при использовании простых обещаний:
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
Более простая отладка
Отладка обещаний сложна, потому что отладчик не будет переступать через асинхронный код.
Async/await делает это очень простым, потому что для компилятора это похоже на синхронный код.
Оригинал: “https://flaviocopes.com/javascript-async-await/”