js的异步模式从回调函数->Promise->generator/yield->async/await
回调函数和Promise都有回调地狱的问题,代码不利于阅。generator/yield虽然解决了回调地狱的问题,但是需要开发者自己写迭代器的逻辑。
而async/await即解决了回调地狱的问题,同时将 Generator 函数和自动执行器,封装在一个函数中,它其实就是generator的语法糖。只是开发者不用再关心内部复杂的实现逻辑
注意点:
- await命令只能用在async函数之中,如果用在普通函数,会报错
- async函数的返回值是 Promise 对象更方便使用
当 async 函数中只要一个 await 出现 reject 状态,则后面的 await 都不会被执行,可以添加 try/catch来捕获异常
原理:
async/await会被编译成generator+promise的语法代码
async function fn() {
// ...
}
等价于
function fn() {
return spawn(function * () {
// spawn 是自执行器
// ...
})
}
function spawn(genF){
return new Promise((resolve, reject)=>{
const gen = genF() // 先将Generator函数执行下,拿到遍历器对象
// 声明step
function step(nextF) {
let next
try {
next = nextF()
} catch(e){
return reject(e)
}
if(next.done){
return resolve(next.value)
}
Promise.resolve(next.value).then((v)=>{
step(()=>{
return gen.next(v)})
}, (e)=>{
step(()=>{
return gen.throw(e)})
})
};
// 自执行
step(()=> {
return gen.next(undefinex)})
})
}