0

0

如何使用 Generator 函数和 yield 关键字实现一个复杂的状态机?

狼影

狼影

发布时间:2025-10-08 12:01:01

|

462人浏览过

|

来源于php中文网

原创

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

如何使用 generator 函数和 yield 关键字实现一个复杂的状态机?

在 JavaScript 中,利用 Generator 函数和 yield 关键字可以非常优雅地实现一个复杂的状态机。Generator 能暂停和恢复执行的特性,天然适合表达状态流转。

什么是状态机?

状态机是一种计算模型,由一组状态、转移条件和动作组成。任意时刻只能处于一个状态,根据输入触发状态之间的切换。比如自动售货机、登录流程、游戏 AI 都可用状态机建模。

Generator 的核心优势

Generator 函数通过 *function 定义,使用 yield 暂停执行,每次调用 next() 才继续。这让我们可以用同步写法表达异步或分步逻辑,非常适合控制状态流转。

特点包括:

  • 函数执行可中断,保留上下文
  • 通过 next(value) 向内部传值
  • 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;
      }
    }
  }
}

如何使用这个状态机

创建实例并驱动状态变化:

OmniAudio
OmniAudio

OmniAudio 是一款通过 AI 支持将网页、Word 文档、Gmail 内容、文本片段、视频音频文件都转换为音频播客,并生成可在常见 Podcast ap

下载
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 generatorasync function*)配合 for await...of 处理。

总结:Generator + yield 提供了一种线性、清晰的方式来编写复杂状态逻辑。相比一堆 if/else 或状态表,它更易读、易维护,尤其适合工作流、协议解析、UI 导航等场景。

基本上就这些。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

847

2023.08.22

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

448

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

606

2023.08.10

function是什么
function是什么

function是函数的意思,是一段具有特定功能的可重复使用的代码块,是程序的基本组成单元之一,可以接受输入参数,执行特定的操作,并返回结果。本专题为大家提供function是什么的相关的文章、下载、课程内容,供大家免费下载体验。

500

2023.08.04

js函数function用法
js函数function用法

js函数function用法有:1、声明函数;2、调用函数;3、函数参数;4、函数返回值;5、匿名函数;6、函数作为参数;7、函数作用域;8、递归函数。本专题提供js函数function用法的相关文章内容,大家可以免费阅读。

166

2023.10.07

promise的用法
promise的用法

“promise” 是一种用于处理异步操作的编程概念,它可以用来表示一个异步操作的最终结果。Promise 对象有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。Promise的用法主要包括构造函数、实例方法(then、catch、finally)和状态转换。

337

2023.10.12

html文本框类型介绍
html文本框类型介绍

html文本框类型有单行文本框、密码文本框、数字文本框、日期文本框、时间文本框、文件上传文本框、多行文本框等等。详细介绍:1、单行文本框是最常见的文本框类型,用于接受单行文本输入,用户可以在文本框中输入任意文本,例如用户名、密码、电子邮件地址等;2、密码文本框用于接受密码输入,用户在输入密码时,文本框中的内容会被隐藏,以保护用户的隐私;3、数字文本框等等。

429

2023.10.12

点击input框没有光标怎么办
点击input框没有光标怎么办

点击input框没有光标的解决办法:1、确认输入框焦点;2、清除浏览器缓存;3、更新浏览器;4、使用JavaScript;5、检查硬件设备;6、检查输入框属性;7、调试JavaScript代码;8、检查页面其他元素;9、考虑浏览器兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

197

2023.11.24

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 6.1万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 3.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号