generator本身不直接实现复杂控制流,而是提供可暂停、可恢复的执行机制,需结合外部调度器(如next()调用、状态机或库)构建异步或分阶段逻辑;yield作为检查点拆解流程,由调用方决策后续行为,支持表单分步、游戏回合、ui状态流等场景,并可配合调度器实现类async/await语法及有限状态机。

Generator 本身不直接“实现”复杂控制流,而是提供一种可暂停、可恢复的函数执行机制,让开发者能用同步风格写出异步或分阶段的逻辑。真正构建复杂控制流,靠的是把 Generator 和外部调度器(比如 next() 调用逻辑、状态机、或封装好的库)结合起来。
用 yield 拆解多步骤流程
把原本嵌套回调或链式 Promise 的步骤,变成一个个可中断的子步骤。每个 yield 表达式就是一个检查点,返回值可被外部读取,外部也可通过 next(value) 注入数据影响后续执行。
- 适合场景:表单分步提交、游戏回合逻辑、状态驱动的 UI 流程(如引导页 → 填写页 → 确认页)
- 示例:一个登录流程 Generator 可以
yield 'checkNetwork',外部检测完网络后调用next(true)继续;若失败则next(false)触发降级逻辑 - 关键点:yield 后不直接处理结果,而是把决策权交给调用方——这正是控制流“可编程”的基础
配合自动调度器实现“类 async/await”行为
手动反复调用 next() 容易出错。写一个简单调度器(或用 co 这类老库),就能让 Generator 自动处理 Promise 并等待 resolve 后继续。
- 调度器核心逻辑:拿到
yield出来的 Promise,.then(res => it.next(res)),错误时it.throw(err) - 这样就能写出类似
const user = yield fetch('/api/user'); const posts = yield fetch(`/api/posts?uid=${user.id}`);的线性代码,但底层仍是 Generator + Promise 协作 - 注意:Generator 不会自动 await,必须有调度器桥接;现代开发更推荐直接用 async/await,但理解这个模式有助于掌握控制流本质
构建有限状态机(FSM)
把每个 yield 视为一个状态出口,外部根据返回值决定下一步走哪个分支,甚至跳转到其他 Generator。
- 例如:电商订单流程中,
yield { type: 'PAYMENT_PENDING' }后,外部根据支付结果决定是next({ status: 'success' })进入发货态,还是next({ status: 'failed', retry: true })回退重试 - 可结合 switch 或 Map 存储不同状态对应的处理函数,让 Generator 成为状态定义载体,而非执行主体
- 优势:状态迁移逻辑清晰、可测试、易扩展(加新状态只需新增 yield 分支和外部响应规则)
与事件系统协同处理用户交互流
在需要响应多次用户操作的场景(如绘图工具的“画线”操作:按下 → 移动 → 抬起),Generator 可挂起等待特定事件,再恢复执行。
- 做法:封装
waitForEvent(el, 'mousedown')返回 Promise,yield它;事件触发后 Promise resolve,Generator 继续运行下一段 - 比嵌套 addEventListener 清晰:避免回调地狱,逻辑集中在 Generator 内,事件监听与业务耦合度低
- 注意:需确保事件监听器能正确清理(如用 AbortController),否则可能内存泄漏
Generator 的价值不在语法糖,而在于它暴露了执行的“暂停权”。复杂控制流的关键,是把决策点显式 yield 出来,再由更上层的逻辑去解释和驱动——这比硬编码 if/else 或 Promise 链更容易适应变化。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











