async/await原理

5 阅读2分钟

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的封装

  • 实现思路
  1. async函数转换成Generator函数。
  2. 使用一个执行器来自动执行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的区别

csdn资源

  1. 代码结构
  • Promise:使用链式调用处理异步操作,代码结构较为扁平,但是多层嵌套后可能变得复杂。
  • async/awit:使用同步代码的风格编写异步操作。
  1. 错误处理
  • Promise:通过catch方法捕获错误,需要在每个Promise链中显示处理错误。
  • async/awit:使用try/catch语句捕获错误,错误处理更加集中和直观。
  1. 可读性
  • Promise:代码逻辑分散在多个then和catch中,阅读时需要跳转。
  • async/awit:代码逻辑集中在一个函数体内,阅读时更加连贯。