Javascript 中 async 和 await 的实现原理

作者:Administrator 发布时间: 2026-05-13 阅读量:4 评论数:0

async/await 的实现原理基于 Generator 函数 + Promise + 自动执行器。本质上是 语法糖,让异步代码看起来像同步代码。

1. 基本原理

async 函数的本质

// async 函数
async function foo() {
  return 1;
}

// 等价于
function foo() {
  return Promise.resolve(1);
}

await 的等待机制

async function bar() {
  const result = await promise;
  console.log(result);
}

// 等价于
function bar() {
  return promise.then(result => {
    console.log(result);
  });
}

2. 底层实现:Generator + Promise

核心原理代码

// 1. 模拟 async 函数
function asyncGenerator(generatorFunc) {
  return function (...args) {
    const generator = generatorFunc.apply(this, args);
    
    return new Promise((resolve, reject) => {
      function step(key, arg) {
        let result;
        try {
          result = generator[key](arg);
        } catch (error) {
          return reject(error);
        }
        
        const { value, done } = result;
        
        if (done) {
          return resolve(value);
        }
        
        // 确保 value 是 Promise
        Promise.resolve(value).then(
          val => step("next", val),
          err => step("throw", err)
        );
      }
      
      step("next");
    });
  };
}

// 2. 使用示例
const myAsyncFunc = asyncGenerator(function* () {
  const result1 = yield Promise.resolve(1);
  console.log(result1); // 1
  
  const result2 = yield Promise.resolve(2);
  console.log(result2); // 2
  
  return result1 + result2;
});

myAsyncFunc().then(console.log); // 3

3. Babel 转译示例

async/await 源代码

async function example() {
  const a = await Promise.resolve('A');
  const b = await Promise.resolve('B');
  return a + b;
}

Babel 转译后的代码

function _asyncToGenerator(fn) {
  return function () {
    const self = this;
    const args = arguments;
    
    return new Promise((resolve, reject) => {
      const gen = fn.apply(self, args);
      
      function _next(value) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
      }
      
      function _throw(err) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
      }
      
      _next(undefined);
    });
  };
}

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  try {
    var info = gen[key](arg);
    var value = info.value;
  } catch (error) {
    reject(error);
    return;
  }
  
  if (info.done) {
    resolve(value);
  } else {
    Promise.resolve(value).then(_next, _throw);
  }
}

// 转译后的 example 函数
var example = _asyncToGenerator(function* () {
  const a = yield Promise.resolve('A');
  const b = yield Promise.resolve('B');
  return a + b;
});

4. 完整实现原理

手写简易 async/await

class MyAsync {
  constructor(generatorFunc) {
    this.generatorFunc = generatorFunc;
  }
  
  run(...args) {
    const generator = this.generatorFunc.apply(this, args);
    
    return new Promise((resolve, reject) => {
      const onFulfilled = (res) => {
        let result;
        try {
          result = generator.next(res);
        } catch (e) {
          return reject(e);
        }
        next(result);
      };
      
      const onRejected = (err) => {
        let result;
        try {
          result = generator.throw(err);
        } catch (e) {
          return reject(e);
        }
        next(result);
      };
      
      const next = ({ value, done }) => {
        if (done) {
          return resolve(value);
        }
        
        // 如果 value 不是 Promise,包装成 Promise
        const promise = value instanceof Promise 
          ? value 
          : Promise.resolve(value);
          
        promise.then(onFulfilled, onRejected);
      };
      
      onFulfilled();
    });
  }
}

// 使用示例
const asyncFunc = new MyAsync(function* () {
  console.log('开始');
  
  const data1 = yield new Promise(resolve => 
    setTimeout(() => resolve('数据1'), 1000)
  );
  console.log(data1);
  
  const data2 = yield new Promise(resolve => 
    setTimeout(() => resolve('数据2'), 500)
  );
  console.log(data2);
  
  return '完成';
});

asyncFunc.run().then(console.log); // 输出:开始 -> 数据1 -> 数据2 -> 完成

5. 错误处理机制

try/catch 的实现

async function asyncWithTryCatch() {
  try {
    const result = await Promise.reject('错误');
    return result;
  } catch (error) {
    console.log('捕获错误:', error);
    return '默认值';
  }
}

// 转译实现
function* generatorWithTryCatch() {
  let result;
  try {
    result = yield Promise.reject('错误');
    return result;
  } catch (error) {
    console.log('捕获错误:', error);
    return '默认值';
  }
}

6. 并行执行优化

await 的串行 vs 并行

// 串行执行(慢)
async function serial() {
  const start = Date.now();
  
  const a = await fetchA(); // 假设 1秒
  const b = await fetchB(); // 假设 1秒
  
  console.log(`串行耗时: ${Date.now() - start}ms`); // ~2000ms
  return { a, b };
}

// 并行执行(快)
async function parallel() {
  const start = Date.now();
  
  const promiseA = fetchA(); // 立即开始
  const promiseB = fetchB(); // 立即开始
  
  const a = await promiseA;
  const b = await promiseB;
  
  console.log(`并行耗时: ${Date.now() - start}ms`); // ~1000ms
  return { a, b };
}

// 实现原理:Promise.all 的语法糖
async function parallelWithAll() {
  const [a, b] = await Promise.all([fetchA(), fetchB()]);
  return { a, b };
}

7. 微任务队列机制

async function microtaskDemo() {
  console.log(1);
  
  await Promise.resolve();
  console.log(2); // 微任务
  
  console.log(3);
}

console.log('开始');
microtaskDemo();
console.log('结束');

// 输出顺序:开始 -> 1 -> 结束 -> 2 -> 3
// 原理:await 后面的代码会被包装成微任务

8. 实际应用:实现 sleep 函数

// 基于 async/await 的 sleep
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function demo() {
  console.log('开始等待');
  await sleep(1000);
  console.log('1秒后');
  await sleep(2000);
  console.log('再2秒后');
}

// 实现原理
function* sleepGenerator() {
  yield new Promise(resolve => setTimeout(resolve, 1000));
  console.log('1秒后');
  yield new Promise(resolve => setTimeout(resolve, 2000));
  console.log('再2秒后');
}

9. 性能优化技巧

// 1. 避免不必要的 await
async function unnecessaryAwait() {
  // ❌ 不需要 await
  const data = await fetchData();
  return data;
  
  // ✅ 直接返回 Promise
  return fetchData();
}

// 2. 批量处理
async function batchProcess(items) {
  // ❌ 逐个等待
  for (const item of items) {
    await processItem(item);
  }
  
  // ✅ 批量处理
  const promises = items.map(item => processItem(item));
  await Promise.all(promises);
}

// 3. 提前启动 Promise
async function earlyStart() {
  // ❌ 顺序执行
  const data1 = await api1();
  const data2 = await api2(data1);
  
  // ✅ 提前启动
  const promise1 = api1();
  const data1 = await promise1;
  const data2 = await api2(data1);
}

总结原理要点

  1. async 函数:总是返回 Promise

  2. await:暂停函数执行,等待 Promise 解决

  3. 底层机制:Generator + 自动执行器

  4. 执行流程

    • 遇到 await → 暂停执行

    • Promise 解决 → 恢复执行(微任务)

    • 继续执行后续代码

  5. 错误处理:通过 try/catch 或 .catch() 处理

  6. 性能优化:注意并行执行,避免不必要的等待

核心思想:async/await 通过 暂停-恢复 机制,让异步代码拥有同步代码的书写方式,同时保持非阻塞的特性。

评论