生成器函数通过yield暂停执行并配合执行器(如co或自定义runner)实现异步流程控制,本质是手动调度promise的resolve后调用next()恢复;async/await是其语法级替代方案,更简洁可靠。

JavaScript 中生成器函数(Generator Function)本身不直接处理异步,但配合 yield 和手动/自动的执行器(如 co 或自定义 runner),可以将异步操作“暂停-恢复”式地组织起来,实现类似同步书写的异步流程控制。
理解生成器函数的基本行为
生成器函数用 function* 声明,返回一个迭代器对象。每次调用 next() 会执行到下一个 yield 表达式并暂停,把 yield 后的值作为 { value, done } 返回。
关键点:yield 不是等待,只是暂停;真正控制异步时机的是外部如何处理 yield 出来的值(比如 Promise)并决定何时调用下一次 next()。
手动用 next() 驱动异步流程
你可以自己写一个简单的 runner:当 yield 出一个 Promise 时,等它 resolve 后再调用 next(result) 继续执行。
- 定义生成器函数,
yieldPromise(如fetch、setTimeout封装) - 创建递归函数,接收迭代器,调用
next(),检查是否完成;若未完成且value是 Promise,则.then(res => run(res)) - 这样就把“等待异步结果 → 恢复执行”逻辑封装起来了
用 co 库或现代替代方案简化
co 是早期流行工具,自动运行生成器,支持 yield Promise、数组、对象等,并统一处理错误。
示例:
const co = require('co');co(function* () {
const user = yield fetch('/api/user');
const data = yield user.json();
console.log(data);
}).catch(err => console.error(err));
注意:ES2017 起,async/await 已成为标准方案,语义更清晰、调试更友好,co + generator 主要用于兼容旧环境或特殊控制流场景。
和 async/await 的关系与取舍
生成器 + runner 是 async/await 的思想前身。两者都让异步代码看起来像同步,但:
-
async/await是语言级语法,原生支持,无需额外库或手动驱动 - 生成器更底层、更灵活(可 yield 非 Promise,可双向通信),但也更复杂、易出错
- 除非需要定制执行语义(如暂停/恢复、多任务调度、协程式状态机),否则优先用
async/await
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











