async/await工作原理

搞懂 Promise

async/await 是 Promise 的语法糖,所以得先知道 Promise 是什么。

Promise 本质上就是一个状态机,三种状态:

  • pending:等待中

  • fulfilled:成功了

  • rejected:失败了

状态只能从 pending 变成另外两种,而且不可逆。


const p = new Promise((resolve, reject) => {
  setTimeout(() => resolve('done'), 1000);
});

p.then(result => console.log(result)); // 1秒后打印 "done"

事件循环

要理解 async/await,必须知道事件循环(Event Loop)。

JavaScript 的执行模型大概是这样:

调用栈(Call Stack)
    ↓ 同步代码在这里执行
    
微任务队列(Microtask Queue)
    ↓ Promise.then、queueMicrotask 等
    
宏任务队列(Macrotask Queue)
    ↓ setTimeout、setInterval、I/O 等

async/await 的真面目

async 函数本质上是一个返回 Promise 的函数。

async function foo() {
  return 42;
}

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

await 则是暂停当前 async 函数的执行,等 Promise 完成后再继续。

用伪代码理解:

async function fetchUser() {
  const res = await fetch('/api/user');
  const data = await res.json();
  return data;
}

// 大概等价于
function fetchUser() {
  return fetch('/api/user').then(res => {
    return res.json().then(data => {
      return data;
    });
  });
}

错误处理

async/await 的错误处理比 Promise 链直观很多:

// Promise 链写法
fetch('/api/user')
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

// async/await 写法
async function fetchUser() {
  try {
    const res = await fetch('/api/user');
    const data = await res.json();
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

手写一个 Promise

class MyPromise {
  constructor(executor) {
    this.state = 'pending';
    this.value = undefined;
    this.callbacks = []; // 存放 then 注册的回调

    const resolve = (value) => {
      if (this.state !== 'pending') return;
      this.state = 'fulfilled';
      this.value = value;
      // 通知所有等待的回调
      this.callbacks.forEach(cb => cb.onFulfilled(value));
    };

    const reject = (reason) => {
      if (this.state !== 'pending') return;
      this.state = 'rejected';
      this.value = reason;
      this.callbacks.forEach(cb => cb.onRejected(reason));
    };

    try {
      executor(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }

  then(onFulfilled, onRejected) {
    // 返回新的 Promise,支持链式调用
    return new MyPromise((resolve, reject) => {
      const handle = (fn, val) => {
        // 用 queueMicrotask 模拟微任务
        queueMicrotask(() => {
          try {
            const result = fn(val);
            // 如果返回的也是 Promise,等它完成
            if (result instanceof MyPromise) {
              result.then(resolve, reject);
            } else {
              resolve(result);
            }
          } catch (err) {
            reject(err);
          }
        });
      };

      if (this.state === 'fulfilled') {
        handle(onFulfilled, this.value);
      } else if (this.state === 'rejected') {
        handle(onRejected, this.value);
      } else {
        // 还在 pending,先存起来等 resolve/reject 触发
        this.callbacks.push({
          onFulfilled: val => handle(onFulfilled, val),
          onRejected: val => handle(onRejected, val),
        });
      }
    });
  }

  catch(onRejected) {
    return this.then(null, onRejected);
  }

  static resolve(value) {
    return new MyPromise(resolve => resolve(value));
  }

  static reject(reason) {
    return new MyPromise((_, reject) => reject(reason));
  }
}


async/await工作原理
http://localhost:8090/archives/async-awaitgong-zuo-yuan-li
作者
Administrator
发布于
2025年11月07日
许可协议