Generator 函数实现 async/await 异步控制流
在 JavaScript 中,Generator 函数可以配合 yield 关键字实现类似 async/await 的异步控制流。以下是详细解释和实现步骤:
核心原理
- Generator 特性:可以暂停执行(
yield)和恢复执行(next()) - 异步处理:当遇到异步操作时暂停执行,操作完成后再恢复
- 自动执行:需要一个执行器(runner)来管理 Generator 的流程
实现步骤(含完整代码)
// 1. 定义异步执行器
function runGenerator(genFunc) {
const generator = genFunc();
function handle(result) {
if (result.done) return result.value;
return Promise.resolve(result.value)
.then(res => handle(generator.next(res))) // 成功时恢复执行
.catch(err => handle(generator.throw(err))); // 错误时抛出异常
}
try {
return handle(generator.next());
} catch (err) {
return Promise.reject(err);
}
}
// 2. 创建模拟异步函数
function fetchData(url, delay) {
return new Promise(resolve => {
setTimeout(() => resolve(`来自 ${url} 的数据`), delay);
});
}
// 3. 使用 Generator 定义异步流程
function* main() {
try {
console.log("开始请求");
// yield 暂停执行,等待 Promise 完成
const data1 = yield fetchData("https://api.example.com/users", 1000);
console.log("收到数据1:", data1);
const data2 = yield fetchData("https://api.example.com/posts", 800);
console.log("收到数据2:", data2);
return "所有操作完成!";
} catch (error) {
console.error("捕获错误:", error);
return "处理错误";
}
}
// 4. 执行异步流程
runGenerator(main)
.then(finalResult => console.log("最终结果:", finalResult))
.catch(err => console.error("未处理的错误:", err));
执行流程解析:
-
初始化:
runGenerator(main)创建生成器对象- 首次调用
generator.next()启动生成器
-
首次异步操作:
- 遇到
yield fetchData(...)暂停执行 - 执行器等待 Promise 完成
- 1秒后 Promise 完成,将结果传给
generator.next(res)
- 遇到
-
恢复执行:
- 生成器从暂停点继续
data1获得异步结果- 执行到下一个
yield再次暂停
-
后续操作:
- 重复上述过程直到所有
yield完成 - 最终返回
return的值
- 重复上述过程直到所有
-
错误处理:
- 如果任何 Promise 被拒绝(reject)
- 执行器调用
generator.throw(err) - 在生成器中被
try/catch捕获
关键优势:
- 同步化写法:用同步代码风格写异步逻辑
- 流程控制:轻松实现顺序执行(无需回调嵌套)
- 错误处理:使用
try/catch统一处理错误
实际输出示例:
开始请求
(等待1秒...)
收到数据1: 来自 https://api.example.com/users 的数据
(等待0.8秒...)
收到数据2: 来自 https://api.example.com/posts 的数据
最终结果: 所有操作完成!
对比 async/await:
// 等效的 async/await 实现
async function mainAsync() {
const data1 = await fetchData("https://api.example.com/users", 1000);
const data2 = await fetchData("https://api.example.com/posts", 800);
return "所有操作完成!";
}
Generator 方案本质上实现了 async/await 的底层机制,但需要手动管理执行流程。
适用场景:
- 需要兼容不支持 async/await 的老环境
- 需要更精细控制异步流程(如中间暂停)
- 实现自定义高级异步模式(如取消操作)
注意:现代 JavaScript 中应优先使用 async/await,但理解 Generator 实现原理有助于深入掌握异步编程模型。

浙公网安备 33010602011771号