Для тех, кто не знаком с Generator, вы можете сначала просмотреть документацию Generator:developer.Mozilla.org/this-cn/docs/…
предисловие
До ES2017, если мы хотели написать часть асинхронного логического программирования в виде синхронного кода, нам нужно было полагаться на генератор, например:
function getJSONFile() {
return new Promise(function(resolve, reject){
setTimeout(function(){
resolve({
name: '大漠传奇',
age: 23,
})
}, 1000)
})
}
function getHobby() {
return new Promise(function(resolve, reject){
setTimeout(function(){
resolve({
hobby: ['爬山','旅游','听歌','看电影','看小说','打游戏'],
})
}, 1000)
})
}
function* gen(i) {
let me = yield getJSONFile();
console.log('me:', me);
let hobby = yield getHobby();
console.log('hobby:', hobby)
}
function co(genFn) {
let gen = genFn();
let res = gen.next()
let run = (gen, res) => {
if(!res.done){
if(res.value&&(res.value.__proto__.constructor === Promise)){
res.value.then((data) => {
let res2 = gen.next(data)
run(gen, res2);
})
}else{
let res3 = gen.next(res.value);
run(gen, res3);
}
}
}
run(gen, res);
}
co(gen)
Однако после того, как ES2017 предоставит async && await, приведенный выше код можно будет написать более элегантно. Например:
// async await
async function likeGen() {
let me = await getJSONFile();
console.log('me:', me);
let hobby = await getHobby();
console.log('hobby:', hobby);
return 'end';
}
likeGen().then(res => {
console.log('res:', res);
})
Если сравнить их с использованием async+await для записи, наиболее очевидным изменением будет то, что на одну функцию co меньше, а объем кода будет меньше. Остальной код похож на реализацию генератора. Так почему же ES2017 предоставляет async && await для написания синхронного кода с меньшим количеством кода и большим удобством?
Давайте представим конкретные причины ниже.Давайте сначала посмотрим на введение функции async && await.
async && a ждать функций
async
Объявление асинхронной функции используется для определения асинхронной функции, которая возвращает объект AsyncFunction. Асинхронная функция — это функция, которая выполняется асинхронно через цикл обработки событий и возвращает результат через неявное обещание. Но если ваш код использует асинхронные функции, его синтаксис и структура будут больше похожи на стандартные синхронные функции.
Когда вызывается асинхронная функция, она возвращает объект Promise. Когда асинхронная функция возвращает значение, за передачу этого значения будет отвечать метод разрешения промиса; когда асинхронная функция выдает исключение, метод отклонения промиса также передает значение исключения.
В асинхронной функции может быть выражение ожидания, которое заставит асинхронную функцию приостановить выполнение, дождаться выхода результата обещания, а затем возобновить выполнение асинхронной функции и вернуть разрешенное значение (разрешено).
Обратите внимание, что ключевое слово await допустимо только в асинхронных функциях. Если вы используете await вне асинхронной функции, вы просто получите SyntaxError.
await
Оператор await используется для ожидания объекта Promise. Его можно использовать только в асинхронных функциях.
Выражение await приостанавливает выполнение текущей асинхронной функции и ожидает завершения обещания. Если обещание обрабатывается нормально (выполняется), параметр функции разрешения его обратного вызова используется в качестве значения выражения ожидания, а асинхронная функция продолжает выполняться.
Если обещание обработано, выражение AWAIT выдаст причину проксимации обещания.
Кроме того, если значение выражения, следующего за оператором await, не является промисом, возвращается само значение.
async+await VS generator
Цель введения async и await в ES2017 — упростить утомительное использование генераторов для написания синхронного кода, уменьшить сложность использования js для написания синхронного кода, уменьшить объем кода и упростить синтаксис.
Вы можете понять асинхронность и ждать, когдапредисловиеПервая половина средней части использует генератор для реализации простого синтаксического сахара верхнего уровня синхронного кода. То есть браузер помогает нам реализовать базовую часть в интерпретаторе js.Когда мы используем async и await, интерпретатор js будет понимать это как функцию генератор+со (генератор автоматически выполняет функцию, реализованную в предисловии).
Таким образом, нам не нужно обращать внимание на генератор и на то, как заставить генератор выполняться автоматически.Чтобы написать синхронный код, нам нужно только определить асинхронную функцию и использовать ожидание в асинхронной функции, чтобы дождаться успешного завершения. выполнение асинхронного кода. То есть просто и удобно, объем кода все равно небольшой.