Generator 结合状态机模式可将异步逻辑写得如同步代码般清晰:每个 yield 代表一个状态节点,next() 触发迁移,结构化输出状态、避免内部副作用,并配合调度器衔接 Promise 实现可暂停异步流程。

Generator 结合状态机模式,能将异步或分步逻辑写得像同步代码一样清晰——核心在于用 yield 显式暂停/恢复执行,并把每个 yield 视为一个状态节点,由外部驱动流转。
用 Generator 模拟有限状态机(FSM)结构
Generator 函数天然具备“可暂停、可恢复、带局部状态”的特性,非常适合表达状态转移。每个 yield 后的值可代表当前状态标识(如字符串、符号或对象),而 next(value) 的调用则相当于触发状态迁移事件。
- 定义 Generator 函数,内部用
while (true)或条件分支模拟状态循环 - 每次
yield返回当前状态数据(如{ type: 'LOADING', data: null }),同时等待外部输入决定下一步 - 通过
next(input)传入动作(如'SUCCESS'或{ type: 'ERROR', msg: '...' }),在函数体内用switch或if处理迁移逻辑
一个登录流程的状态机示例
以下是一个简明但完整的登录状态机实现:
function* loginStateMachine() {
let user = null;
<p>while (true) {
switch (yield { type: 'IDLE' }) {
case 'START':
yield { type: 'LOADING' };
// 模拟异步请求(实际中可配合 Promise + await 或手动调度)
break;</p><pre class="brush:php;toolbar:false;"> case 'SUCCESS':
user = yield { type: 'SUCCESS', user: { id: 1, name: 'Alice' } };
break;
case 'ERROR':
yield { type: 'ERROR', message: 'Login failed' };
break;
case 'LOGOUT':
user = null;
yield { type: 'IDLE' };
break;
default:
yield { type: 'ERROR', message: 'Unknown action' };
}} }
// 使用方式(配合简单调度器) const machine = loginStateMachine(); console.log(machine.next().value); // { type: 'IDLE' } console.log(machine.next('START').value); // { type: 'LOADING' } console.log(machine.next('SUCCESS').value); // { type: 'SUCCESS', user: ... }
注意:这里未直接 await 异步操作,是因为 Generator 本身不执行异步——它只定义状态流;真正调度需由外部协调器(如封装成 async 函数或配合 co 库)来衔接 Promise。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
搭配异步调度器,实现“可暂停的异步流程”
要让 Generator 真正驱动真实异步任务(如 API 调用),需要一个调度器把 yield Promise 和 next(result) 连接起来:
- 让 Generator 直接
yield fetch('/login'),调度器捕获 Promise 并自动.then(res => it.next(res)) - 推荐轻量方案:用
async function run(gen) { const it = gen(); async function next(val) { const { value, done } = it.next(val); return done ? value : value.then ? next(await value) : next(value); } return next(); } - 这样就能写出形如
yield api.login(credentials)的语句,既保持线性阅读感,又明确标出异步断点
关键设计提醒
写这类代码时,容易忽略但影响可维护性的细节:
- 状态输出应结构化(如统一返回
{ type, payload? }),方便 UI 层switch (state.type)渲染 - 避免在 Generator 内部做副作用(如直接修改全局变量或 DOM),所有状态变更应通过
yield输出,由外部消费并响应 - 错误处理建议用
try/catch包裹 yield 表达式,或约定特定 action(如'THROW')触发异常迁移 - 可配合 TypeScript 定义
type LoginState = 'IDLE' | 'LOADING' | 'SUCCESS' | 'ERROR',提升类型安全

















