新闻中心

使用J*aScript实现一个简单的状态机_j*ascript设计模式

2025-11-04
浏览次数:
返回列表
状态机用于管理对象行为随状态变化的逻辑。在J*aScript中,通过定义状态、事件、转移规则和动作,可实现清晰的状态流转控制。文中给出了一个简易StateMachine类,支持初始化配置、状态切换及事件触发,并通过示例展示了播放器和开关灯的状态管理。进一步扩展了带onEnter和onExit钩子的状态机,支持状态变更时执行副作用函数,提升灵活性。该设计适用于按钮控制、页面流程等场景,具备良好可维护性,建议在生产环境中补充校验与调试机制。

使用javascript实现一个简单的状态机_javascript设计模式

状态机是一种处理对象行为随状态变化而变化的设计模式。在J*aScript中,状态机可以帮助我们清晰地管理复杂的状态流转逻辑,比如按钮的启用/禁用、页面流程控制等场景。下面是一个简单但实用的状态机实现。

基本概念

一个状态机包含:

  • 状态(State):对象当前所处的阶段,如“空闲”、“运行”、“暂停”
  • 事件(Event):触发状态变化的动作,如“开始”、“停止”
  • 转移规则(Transitions):定义在某个状态下,某个事件触发后应切换到哪个新状态
  • 动作(Actions):状态改变时执行的副作用函数

实现一个简易状态机

我们可以封装一个通用的StateMachine类,支持定义状态、事件和转移逻辑。

class StateMachine {
  constructor(config) {
    this.state = config.initial; // 初始状态
    this.transitions = config.transitions || {};
  }

  // 获取当前状态
  getState() {
    return this.state;
  }

  // 触发事件,尝试状态转移
  trigger(event) {
    const transition = this.transitions[this.state]?.[event];
    if (transition) {
      this.state = transition;
      return true;
    }
    console.warn(`无法在状态 '${this.state}' 下触发事件 '${event}'`);
    return false;
  }
}

使用示例:模拟一个播放器的状态控制

Shoping购物网源码 Shoping购物网源码

该系统采用多层模式开发,这个网站主要展示女装的经营,更易于网站的扩展和后期的维护,同时也根据常用的SQL注入手段做出相应的防御以提高网站的安全性,本网站实现了购物车,产品订单管理,产品展示,等等,后台实现了动态权限的管理,客户管理,订单管理以及商品管理等等,前台页面设计精致,后台便于操作等。实现了无限子类的添加,实现了动态权限的管理,支持一下一个人做的辛苦

Shoping购物网源码 0 查看详情 Shoping购物网源码
const playerSM = new StateMachine({
  initial: 'idle',
  transitions: {
    idle: {
      play: 'playing'
    },
    playing: {
      pause: 'paused',
      stop: 'idle'
    },
    paused: {
      play: 'playing',
      stop: 'idle'
    }
  }
});

console.log(playerSM.getState()); // 'idle'
playerSM.trigger('play');
console.log(playerSM.getState()); // 'playing'
playerSM.trigger('pause');
console.log(playerSM.getState()); // 'paused'

扩展:支持状态变更钩子

实际开发中,状态变化常伴随UI更新或数据请求。可以加入onEnteronExit钩子增强灵活性。

class StateMachineWithActions {
  constructor(config) {
    this.state = config.initial;
    this.transitions = config.transitions || {};
    this.actions = config.actions || {};
  }

  trigger(event) {
    const nextState = this.transitions[this.state]?.[event];
    if (!nextState) {
      console.warn(`无效转换: ${this.state} + ${event}`);
      return false;
    }

    // 执行离开当前状态的动作
    this.actions.onExit?.[this.state]?.();

    this.state = nextState;

    // 执行进入新状态的动作
    this.actions.onEnter?.[this.state]?.();

    return true;
  }

  getState() {
    return this.state;
  }
}

带动作的使用示例:

const lightSM = new StateMachineWithActions({
  initial: 'off',
  transitions: {
    off: { switch: 'on' },
    on: { switch: 'off' }
  },
  actions: {
    onEnter: {
      on: () => console.log('灯已打开'),
      off: () => console.log('灯已关闭')
    }
  }
});

lightSM.trigger('switch'); // 输出:灯已打开
lightSM.trigger('switch'); // 输出:灯已关闭
基本上就这些。这个简单的状态机设计清晰、易于维护,适合中小型项目中的状态逻辑抽象。不复杂但容易忽略的是边界处理和错误提示,生产环境中建议加上更完善的校验和调试支持。

以上就是使用J*aScript实现一个简单的状态机_j*ascript设计模式的详细内容,更多请关注其它相关文章!


# 是一个  # 天水关键词推广排名  # 宜昌网站建设项目教程书  # SEO8860520  # 哈尔滨seo优化战略  # 河北网站建设选迅法网  # 网站推广企业如何优化  # 营销推广中心的职能  # 兰州正规seo公司报价  # 营销推广活动心得  # 临汾网站优化排名软件  # 有何不同  # javascript  # 的是  # 端到  # 如何实现  # 如何用  # 命令行  # 播放器  # 实现了  # 购物网  # switch  # mac  # java 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: Golang如何实现简单的Web表单_Golang表单提交与验证处理方法  PHP中SSG-WSG API的AES加密实践:正确使用初始化向量  一加 Nord 5 隐私权限异常_一加 Nord 5 系统安全优化  蓝湖怎样用切图标注提对接效率_蓝湖用切图标注提对接效率【设计对接】  利用Bokeh CustomJS动态控制DataTable列可见性  12306选座系统怎么选连座_12306选座多人连坐操作方法  Python模块化编程:有效管理依赖与避免循环引用  Win11怎么修改默认浏览器_Windows 11设置Chrome为默认  Log4j Console Appender性能瓶颈与高并发优化策略  PDO预处理语句中冒号的正确处理:区分SQL函数格式与命名占位符  Safari怎么安装扩展程序 浏览器插件安装与管理方法【详解】  如何使用Rector自动化升级旧代码_通过Composer安装和配置Rector进行代码重构  小红书网页版入口链接分享 小红书官网直接进  在哪找SublimeJ远程工具_SFTP插件配置教程  消息称三星明年 2 月正式发布 HBM4,与 SK 海力士同台竞技  Flexbox布局实践:实现粘性导航栏与底部固定页脚  AO3官网镜像链接 Archive of Our Own同人文在线浏览  AO3中文官网链接_AO3网页版稳定镜像站  c++如何使用Meson构建系统_c++比CMake更快的构建工具  HTML5原生日期选择器与jQuery UI:实现日期选择器的联动与程序化控制  VS Code远程开发时如何处理文件权限问题  Spring Boot内嵌服务器与J*a EE全栈特性:选择与部署策略  Win11怎么开启高性能模式_Windows 11电源计划优化设置  如何使用J*aScript精确选择并批量修改特定父元素下子链接的样式  解决移动端滚动问题的overflow属性应用指南  汽水音乐在线解析 汽水音乐在线解析入口  怎么去除衣服上的口红印_生活小妙招教你用酒精轻松擦除  c++中为什么推荐使用using替代typedef_c++现代化类型别名  铁路12306改签能改到更早的车次吗_铁路12306改签提前车次规则  如何在Python中使用Optional类型处理可变对象并避免Pylint警告  解决深度学习模型训练初期异常高损失与完美验证准确率问题  Golang如何测试channel通信行为_Golang channel通信测试与分析方法  Pandas DataFrame:高效添加条件计算列  J*a递归快速排序中静态变量的状态管理与陷阱  Win11蓝牙耳机断连怎么解决 Win11蓝牙设置重新配对与驱动更新【技巧】  一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法  css绝对定位元素脱离父容器怎么办_确保父元素position非static  C#如何安全地从用户上传的XML文件中读取数据? 验证与清理策略  Python vgamepad库按键模拟:正确使用XUSB_BUTTON常量  顺丰国际快递查询 国际件官方查询入口  微信客户端如何收红包_微信客户端接收红包使用教程  ACG动漫视频网入口 ACG动漫*免费正版观看地址  优化Log4j2控制台输出性能:解决异步日志瓶颈  Python多版本共存与虚拟环境管理深度指南  QQ邮箱网页版入口 QQ邮箱官方邮箱登录通道  Tabulator表格日期时间排序问题及自定义解决方案  微信群消息显示延迟如何解决 微信群消息刷新优化方法  css子元素高度不一致导致布局错位怎么办_使用align-items:stretch解决高度差异  Excel如何用迷你图显趋势_Excel用迷你图显趋势【趋势小图】  解决macOS上安装pyhdf时‘hdf.h’文件缺失的编译错误 

搜索