Generator 通过 yield 暂停执行并由外部 runner 驱动 next() 实现状态机,每个 yield 是状态跳转点,传入值作输入,Promise resolve 后自动恢复,配合 try/catch 和 yield* 支持错误处理与子状态嵌套。

Generator 本身不直接执行异步操作,而是通过 yield 暂停执行 + 外部驱动器(如 runner 或 Promise 链)恢复执行,把异步流程拆成“状态片段”,每个 yield 相当于一个状态跳转点。关键在于:Generator 函数返回迭代器,每次 next() 触发一次状态迁移,而传入的值可作为“跳转输入”影响后续行为。
Generator 构建状态节点:每个 yield 是一个暂停点
Generator 内部用 yield 标记状态边界,函数体按顺序执行到 yield 就暂停,保存当前上下文(变量、执行位置)。这天然对应状态机中的“状态停留”。例如:
function* authFlow() {
yield 'login'; // 状态1:等待登录
const user = yield 'fetchProfile'; // 状态2:获取用户信息,接收结果作为输入
if (user.role === 'admin') {
yield 'showAdminPanel';
} else {
yield 'showUserPanel';
}
}
这里每个 yield 表达式就是一个状态出口,其返回值(即 next(value) 中的 value)可作为下个状态的输入,实现条件跳转。
外部 runner 驱动状态流转:接管 next() 并处理 Promise
要让 Generator 支持异步,必须由外部代码捕获 yield 出来的 Promise,并在其 resolve 后调用 next(result) 继续执行。这就是“状态机调度器”:
立即学习“Java免费学习笔记(深入)”;
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 调用
gen.next()启动,得到第一个{ value, done } - 若
value是 Promise,用.then(res => gen.next(res))触发下个状态 - 若
value是普通值(如字符串指令),可交由状态处理器分发,再手动next() - 错误用
gen.throw(err)注入,触发内部try/catch或catch分支
用 try/catch 和 yield* 实现状态分支与嵌套
Generator 支持 try/catch 捕获注入的异常,适合处理跳转失败;yield* 可委托子 Generator,把复杂状态拆成模块:
function* paymentFlow() {
try {
yield 'verifyCard';
yield* chargeFlow(); // 委托另一个状态机
} catch (err) {
yield 'handleFailure'; // 错误状态跳转
}
}
<p>function* chargeFlow() {
yield 'requestAuth';
yield 'processPayment';
}</p>这样,主流程和子流程各自维护状态,yield* 自动透传 next() 和 throw(),相当于状态机的“子状态图嵌入”。
配合 co 或手写自动执行器简化跳转逻辑
手动写 runner 容易出错,可用类似 co 的自动执行器:递归调用 next(),自动展开 Promise、数组、对象等可遍历结构。核心逻辑是:
- 执行
gen.next(value) - 检查
done:为true则结束;否则对value做类型判断 - Promise →
.then(v => run(v));Generator →run(value.next());其他 →run(value)
这种递归驱动让状态跳转完全隐式,开发者只需专注 yield 的语义设计,不用操心调度细节。

















