Generator 天然适合作为状态机控制核心,通过 yield 暂停、next() 恢复实现隐式状态管理,无需手动维护 state 变量或 switch 分支;其执行位置即状态,yield 输出当前状态,next() 输入触发迁移,配合条件判断和状态转移表可构建高可读、可复用的 FSM。

Generator 通过 yield 暂停执行、next() 恢复执行的机制,天然适合作为状态机的控制核心——它把“状态”隐式绑定在函数执行的暂停点上,无需手动维护状态变量或 switch 分支。
用 yield 把每个状态变成一个暂停点
每个 yield 后面的值,可视为当前状态的输出;每次调用 next(),就相当于触发一次状态迁移。Generator 函数体内的执行流,就是状态转移逻辑本身。
- 不需要显式定义 state 变量,状态由执行位置决定(比如刚执行完 yield A,就处于“A 状态”)
- yield 表达式返回值可携带状态数据(如 { type: 'IDLE', payload: null })
- next(value) 的入参可用于向当前状态传入外部输入(例如用户操作、事件结果)
配合 send() 或 next() 实现带输入的状态跃迁
当某个状态需要根据外部输入决定下一步走向时,可在 yield 后接收参数,再用条件判断跳转:
function* buttonStateMachine() {
let status = 'idle';
while (true) {
if (status === 'idle') {
const action = yield { type: 'IDLE' };
if (action === 'click') status = 'pending';
} else if (status === 'pending') {
const result = yield { type: 'PENDING' };
status = result === 'success' ? 'success' : 'error';
} else if (status === 'success') {
yield { type: 'SUCCESS' };
status = 'idle';
}
}
}这样就把传统 switch-case 状态机,转化成了可读性更强、更易调试的线性流程。
立即学习“Java免费学习笔记(深入)”;
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
封装成可复用的状态机工厂
把初始状态、状态转移表抽离出来,让 Generator 更通用:
- 定义 transitions = { stateA: { eventX: 'stateB', eventY: 'stateC' } }
- Generator 内部用 yield 接收事件,查表更新 current,再 yield 新状态
- 对外暴露 next() 和 send(),使用者只关心“发什么事件”,不关心内部跳转细节
这种模式既保留 Generator 的简洁性,又具备有限状态机(FSM)的严谨性,适合表单流程、协议解析、动画帧控制等场景。
注意边界:避免 yield 在异步回调中直接使用
Generator 本身不处理异步,若需等待 Promise,应配合 async/await + 封装器(如 co 库或手写 runner),或改用 AsyncGenerator(支持 await yield)。否则 yield 被包裹在 setTimeout 或 .then 里,会脱离 Generator 控制流,导致状态丢失。
本质上,Generator 提供的是协作式状态调度能力——它不抢控制权,但要求所有状态切换都经由 next() 显式驱动。只要守住这个契约,状态过渡就能自然、可预测、易追溯。

















