状态机是一种由状态、转移条件和动作组成的计算模型,任意时刻仅处于一个状态,如登录流程可用其建模。Generator函数通过yield暂停执行,适合用同步写法控制状态流转,如实现包含“未登录”“登录中”“已登录”“锁定”的认证状态机,每次调用next()传入事件触发状态切换,并返回当前状态,结合yield特性可清晰表达复杂状态逻辑,支持注入副作用,适用于工作流与UI导航等场景。

在 JavaScript 中,利用 Generator 函数和 yield 关键字可以非常优雅地实现一个复杂的状态机。Generator 能暂停和恢复执行的特性,天然适合表达状态流转。
状态机是一种计算模型,由一组状态、转移条件和动作组成。任意时刻只能处于一个状态,根据输入触发状态之间的切换。比如自动售货机、登录流程、游戏 AI 都可用状态机建模。
Generator 函数通过 *function 定义,使用 yield 暂停执行,每次调用 next() 才继续。这让我们可以用同步写法表达异步或分步逻辑,非常适合控制状态流转。
特点包括:
下面是一个模拟用户认证流程的状态机:包含“未登录”、“登录中”、“已登录”、“锁定”四种状态。
function* authStateMachine() {
let state = 'idle';
let attempts = 0;
const maxAttempts = 3;
while (true) {
const { type, password } = yield state;
if (state === 'idle') {
if (type === 'LOGIN') {
if (password === 'secret') {
state = 'authenticated';
} else {
attempts++;
if (attempts >= maxAttempts) {
state = 'locked';
} else {
state = 'pending';
}
}
}
} else if (state === 'pending') {
if (type === 'LOGIN') {
if (password === 'secret') {
state = 'authenticated';
} else {
attempts++;
if (attempts >= maxAttempts) {
state = 'locked';
}
}
}
} else if (state === 'authenticated') {
if (type === 'LOGOUT') {
state = 'idle';
attempts = 0;
}
} else if (state === 'locked') {
if (type === 'RESET') {
state = 'idle';
attempts = 0;
}
}
}
}创建实例并驱动状态变化:
const machine = authStateMachine();
console.log(machine.next().value); // 输出: idle
console.log(machine.next({ type: 'LOGIN', password: 'wrong' }).value); // pending
console.log(machine.next({ type: 'LOGIN', password: 'wrong' }).value); // pending
console.log(machine.next({ type: 'LOGIN', password: 'wrong' }).value); // locked
console.log(machine.next({ type: 'RESET' }).value); // idle
console.log(machine.next({ type: 'LOGIN', password: 'secret' }).value); // authenticated每一步调用 next(input) 相当于发送一个事件,状态机根据当前状态和输入决定下一个状态,并通过 yield state 返回当前状态。
可以在状态转移时插入副作用,比如记录日志、发请求等:
if (state === 'idle' && type === 'LOGIN') {
console.log('正在验证...');
// 模拟异步验证
await new Promise(resolve => setTimeout(resolve, 100));
if (password === 'secret') {
state = 'authenticated';
}
}注意:如果加入 async/await,就无法再用普通 Generator 控制。此时可结合 Thunk 或 Promise 包装器,或者改用 async generator(async function*)配合 for await...of 处理。
总结:Generator + yield 提供了一种线性、清晰的方式来编写复杂状态逻辑。相比一堆 if/else 或状态表,它更易读、易维护,尤其适合工作流、协议解析、UI 导航等场景。
基本上就这些。
以上就是如何使用 Generator 函数和 yield 关键字实现一个复杂的状态机?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号