Generator 实现企业级单向数据流状态机需满足:状态封闭可枚举、迁移仅由预设事件触发、yield 返回纯状态快照、副作用外置、next 输入标准化事件、支持快照与重放、杜绝非确定性操作。

用 Generator 实现企业级单向数据流状态机,关键不是“写个能跑的流程”,而是让状态流转可追溯、不可逆、副作用可控、边界清晰。它不是替代 Redux 或 Zustand,而是在特定模块(如表单向导、审批工作流、设备通信协议)中提供更轻量、更确定的状态控制能力。
状态定义必须封闭且可枚举
所有状态名用常量或 Symbol 声明,禁止字符串硬编码;状态迁移只允许通过预设事件触发,不允许外部直接赋值。
- 定义状态集合:用 Object.freeze({ IDLE: Symbol('IDLE'), PENDING: Symbol('PENDING'), SUCCESS: Symbol('SUCCESS'), ERROR: Symbol('ERROR') }) 确保不可篡改
- 每个状态对应明确的业务语义,比如 PENDING 只表示“正在提交”,不混入“校验中”或“等待确认”等歧义含义
- 初始状态必须显式声明,不能依赖函数内部默认值
yield 表达式即状态出口,只返回纯状态与元信息
每次 yield 不输出副作用结果,只返回当前状态快照 + 可选载荷(payload),例如 { state: STATES.PENDING, payload: { step: 2 } }。真实副作用(如 API 调用、日志上报)应封装在外部处理器中,由调用方根据 yield 返回值决定是否执行。
- Generator 内部不调用 fetch、console.log 或修改全局变量
- yield 后的表达式应为纯对象字面量或简单计算,避免嵌套函数调用
- return 语句仅用于终态(如 return { state: STATES.SUCCESS, completedAt: Date.now() }),不用于中间逻辑分支
next(value) 作为唯一输入通道,强制事件驱动
状态切换完全由外部传入的事件驱动,Generator 自身不监听任何异步源。传入的 value 应是标准化事件对象,含 type 和 data 字段,便于审计与重放。
- 例如:gen.next({ type: 'SUBMIT_START', data: { email: 'a@b.com' } })
- Generator 内部用 switch (event.type) 分发处理,拒绝 if-else 链式判断
- 未识别的 event.type 应 yield 错误状态并保持当前 state,不抛异常(避免中断整个流程)
支持状态快照与可回滚调试
企业级要求可观测性。可在每次 yield 后自动记录快照(state、event、timestamp),并提供 replay(events) 方法还原任意历史路径。
- 快照不存闭包变量,只存 yield 返回值和传入 event
- 提供 getSnapshotHistory() 方法供 DevTools 集成或测试断言
- 禁止在 Generator 内部使用 Date.now()、Math.random() 等非确定性操作,确保重放一致性

















