1. async/await的本质
async/await是Promise的语法糖,本质就是Generator的语法糖
- async函数:用于声明一个异步函数,它会隐式返回一个Promise。
- await表达式:用于等待一个Promise的完成,并返回其resolved的值。如果Promise被reject,await会抛出异常。
async function fetchData() {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
}
2. async函数的实现原理
async函数本质上是一个返回Promise的函数。在函数前加上async关键字时,JavaScript引擎会自动将该函数包装成一个Promise。 下面是两个等价代码 一个是async:
async function foo() {
return 42;
}
一个是Promise
function foo() {
return Promise.resolve(42);
}
3. await的实现原理
await的作用是暂停async函数的执行,直到等待的Promise完成。它的实现依赖于Generator和Promise。
4. async/await的完整实现
async/await的底层实现就是对Generator和Promise的封装
- 实现思路
- 将
async
函数转换成Generator
函数。 - 使用一个执行器来自动执行
Generator
函数,并处理Promise。
function asyncGenerator(generatorFunc) {
return function (...args) {
const generator = generatorFunc(...args);
function handle(result) {
if (result.done) {
return Promise.resolve(result.value)
}
return Promise.resolve(result.value).then((res) => {
handle(generator.next(res))
}).catch((err) => {
handle(generator.throw(err))
})
}
return handle(generator.next())
}
}
5. async/await的注意事件
await
只能在async
函数中使用:如果在普通函数中使用await
,会报语法错误。- 并行执行:多个异步操作时,可以使用Promise.all去实现。
async/await和Promise的区别
- 代码结构
- Promise:使用链式调用处理异步操作,代码结构较为扁平,但是多层嵌套后可能变得复杂。
- async/awit:使用同步代码的风格编写异步操作。
- 错误处理
- Promise:通过catch方法捕获错误,需要在每个Promise链中显示处理错误。
- async/awit:使用try/catch语句捕获错误,错误处理更加集中和直观。
- 可读性
- Promise:代码逻辑分散在多个then和catch中,阅读时需要跳转。
- async/awit:代码逻辑集中在一个函数体内,阅读时更加连贯。