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);
}
总结原理要点
async 函数:总是返回 Promise
await:暂停函数执行,等待 Promise 解决
底层机制:Generator + 自动执行器
执行流程:
遇到 await → 暂停执行
Promise 解决 → 恢复执行(微任务)
继续执行后续代码
错误处理:通过 try/catch 或 .catch() 处理
性能优化:注意并行执行,避免不必要的等待
核心思想:async/await 通过 暂停-恢复 机制,让异步代码拥有同步代码的书写方式,同时保持非阻塞的特性。