新闻中心

使用J*aScript实现一个简单的状态机_js编程思想

2025-10-30
浏览次数:
返回列表
状态机通过定义状态、事件和转移规则来管理对象行为变化。在J*aScript中可用对象实现,如电灯开关有'off'和'on'状态,响应'push'事件切换;进一步可封装为工厂函数createStateMachine,支持初始化、转移和回调,用于订单流程等场景;还可扩展钩子函数onEnter/onExit,实现登录流程中的提示与副作用处理,提升可维护性与扩展性。

使用javascript实现一个简单的状态机_js编程思想

状态机是一种处理对象行为随状态变化而改变的编程模型。在J*aScript中实现一个简单的状态机,可以帮助我们更好地管理组件或对象的复杂状态流转,比如按钮的启用/禁用、页面流程控制等场景。核心思路是:定义状态、定义事件、明确状态如何响应事件进行转移。

1. 状态机的基本结构

一个最简状态机包含三个要素:当前状态(currentState)、允许的状态集合、以及状态转移规则(transitions)。我们可以用对象来描述这些规则,让代码清晰且易于维护。

例如,设计一个电灯开关的状态机:

  • 状态有:'off' 和 'on'
  • 事件有:'push'(按下开关)
  • 规则:'off' + 'push' → 'on';'on' + 'push' → 'off'

基于此,可以写出如下实现:

const lightSwitch = {
  currentState: 'off',
  transitions: {
    off: { push: 'on' },
    on:  { push: 'off' }
  },

  // 触发事件的方法
  trigger(event) {
    const nextState = this.transitions[this.currentState][event];
    if (nextState) {
      this.currentState = nextState;
      console.log(`状态切换为: ${this.currentState}`);
    } else {
      console.warn(`不允许的事件 "${event}" 在状态 "${this.currentState}" 下`);
    }
  }
};

// 使用示例
lightSwitch.trigger('push'); // 输出:状态切换为: on
lightSwitch.trigger('push'); // 输出:状态切换为: off

2. 封装为可复用的函数

为了提升复用性,我们可以将状态机抽象成一个工厂函数,传入配置即可生成不同的状态机实例。

function createStateMachine(config) {
  return {
    currentState: config.initial,
    transitions: config.transitions,

    trigger(event) {
      const currentState = this.currentState;
      const nextState = this.transitions[currentState]?.[event];

      if (nextState) {
        this.currentState = nextState;
        // 可选:执行状态变更后的回调
        if (typeof config.onChange === 'function') {
          config.onChange(currentState, nextState, event);
        }
      } else {
        console.warn(`无效转移: ${currentState} --${event}-> ${nextState}`);
      }
    }
  };
}

使用这个工厂创建一个订单状态机:

SUN2008 企业网站管理系统2.0 beta SUN2008 企业网站管理系统2.0 beta

1、数据调用该功能使界面与程序分离实施变得更加容易,美工无需任何编程基础即可完成数据调用操作。2、交互设计该功能可以方便的为栏目提供个性化性息功能及交互功能,为产品栏目添加产品颜色尺寸等属性或简单的留言和订单功能无需另外开发模块。3、静态生成触发式静态生成。4、友好URL设置网页路径变得更加友好5、多语言设计1)UTF8国际编码; 2)理论上可以承担一个任意多语言的网站版本。6、缓存机制减轻服务器

SUN2008 企业网站管理系统2.0 beta 0 查看详情 SUN2008 企业网站管理系统2.0 beta
const orderMachine = createStateMachine({
  initial: 'pending',
  transitions: {
    pending:   { pay: 'paid', cancel: 'canceled' },
    paid:      { ship: 'shipped', refund: 'refunded' },
    shipped:   { deliver: 'delivered' },
    canceled:  {},
    refunded:  {},
    delivered: {}
  },
  onChange(from, to, event) {
    console.log(`订单从 "${from}" 经 "${event}" 变为 "${to}"`);
  }
});

// 模拟操作
orderMachine.trigger('pay');     // 输出:订单从 "pending" 经 "pay" 变为 "paid"
orderMachine.trigger('ship');    // 输出:订单从 "paid" 经 "ship" 变为 "shipped"
orderMachine.trigger('deliver'); // 输出:订单从 "shipped" 经 "deliver" 变为 "delivered"

3. 添加状态进入/退出的钩子

在实际开发中,状态切换时常需要执行副作用,比如发送请求、更新UI。可以在状态机中加入钩子函数(hooks),增强扩展能力。

改进版:支持每个状态定义 onEnteronExit

function createStateMachineWithHooks(config) {
  let currentState = config.initial;

  function getStateConfig(state) {
    return config.states?.[state] || {};
  }

  return {
    trigger(event) {
      const nextState = config.transitions?.[currentState]?.[event];
      if (!nextState) {
        console.warn(`不允许的事件 "${event}" 在状态 "${currentState}"`);
        return;
      }

      // 执行当前状态的退出逻辑
      const currentConfig = getStateConfig(currentState);
      currentConfig.onExit && currentConfig.onExit();

      // 切换状态
      const previous = currentState;
      currentState = nextState;

      // 执行新状态的进入逻辑
      const nextConfig = getStateConfig(nextState);
      nextConfig.onEnter && nextConfig.onEnter(previous);

      // 外部监听
      config.onChange && config.onChange(previous, nextState, event);
    },

    getState() {
      return currentState;
    }
  };
}

示例:带提示的用户登录流程

const loginMachine = createStateMachineWithHooks({
  initial: 'idle',
  states: {
    idle: {
      onEnter: () => console.log('等待用户操作...')
    },
    loading: {
      onEnter: () => console.log('正在登录...'),
      onExit:  () => console.log('登录请求完成')
    },
    success: {
      onEnter: () => console.log('登录成功!欢迎回来')
    },
    error: {
      onEnter: (from) => console.log(`从 ${from} 登录失败`)
    }
  },
  transitions: {
    idle:     { login: 'loading' },
    loading:  { resolve: 'success', reject: 'error' },
    success:  {},
    error:    { retry: 'idle' }
  }
});

loginMachine.trigger('login');    // 进入 loading
loginMachine.trigger('resolve');  // 进入 success

基本上就这些。通过这种模式,你可以把复杂的条件判断转化为清晰的状态流转,代码更易读、更健壮。尤其适合表单流程、游戏角色行为、UI交互控制等场景。不复杂但容易忽略的是:定义好边界和非法转移,避免状态失控。

以上就是使用J*aScript实现一个简单的状态机_js编程思想的详细内容,更多请关注其它相关文章!


# 多语言  # 四会营销网络推广制度  # 山西品质网站建设价格  # 芦淞区微商营销推广公司  # 河间重型网站建设  # 乐山甜皮鸭营销推广方案  # 通州企业营销推广  # 菏泽自适应网站优化公司  # 湘潭电商型网站建设  # 如何提升网页关键词排名  # 360的SEO搜索特点  # 的是  # 复用  # 它比  # javascript  # 变得更加  # 回调  # 如何使用  # 怎么做  # 企业网站  # 管理系统  # red  # switch  # ai  # mac  # js  # java 


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


相关推荐: 打开就能玩的植物大战僵尸 植物大战僵尸网页版传送门  抖音网页版怎么|直播|_抖音网页版开播操作指南  C++如何进行游戏物理模拟_使用Box2D库为C++游戏添加2D物理效果  AWS EC2实例间SQL Server连接超时:安全组配置与故障排除指南  Golang切片为何属于引用类型_Golang slice底层结构与引用语义说明  2026春节假期时间安排 2026春节假日查询  汽车之家官方网站官网入口_汽车之家网页版直接进入  微信聊天记录怎么加密_微信聊天记录加密方法  蛙漫限时开放最深处链接_蛙漫全站漫画会员同款秒开地址  4399网页游戏电脑版全新入口 4399电脑端在线玩指南  TikTok国际版网页端快速入口 TikTok全球版短视频浏览教程  漫蛙漫画官方主页入口 漫蛙MANWA网页直达访问链接  《明末:渊虚之羽》设计师谈设计角色:那会刚毕业 充满激情  J*aScript实现动态背景色下的文本与按钮颜色自适应调整  台积电1.4nm工艺A14瞄准2028:10年来性能提升80%  J*a编写用户注册与登录功能_掌握字符串与验证逻辑  sublime怎么覆盖插件的默认快捷键_sublime快捷键优先级与设置  《噬血代码2》新预告片发布 展示游戏剧情  vivo手机参数配置怎么增强信号_vivo手机参数配置信号增强方法  2025俄罗斯Yandex最新入口 官方网站地址及浏览器下载指南  如何在Python中使用Optional类型处理可变对象并避免Pylint警告  铁路12306卧铺选择攻略 铁路12306下铺座位预定技巧  J*aScript中向JSON对象添加新属性的正确姿势  J*a里如何实现线程安全的懒加载单例_懒加载单例实现方法解析  Excel函数批量查找替换超快方法_Excel用REPLACE和FIND函数秒级替换  必由学登录入口 必由学官方网站在线访问链接  整合Supabase认证与Django模型:跨模式迁移的解决方案  J*aScript井字棋(Tic-Tac-Toe)核心交互逻辑实现教程  搜狗浏览器如何使用密码生成器创建强密码 搜狗浏览器内置密码安全工具  解决深度学习模型训练初期异常高损失与完美验证准确率问题  天猫双十一预售商品怎么退款_天猫双十一预售退款操作指南  FullCalendar 自定义按钮样式定制指南  jQuery Mask 插件中实现电话号码固定前导零的教程  Safari自带网页翻译功能怎么用 无需插件轻松看懂外文网站【方法】  响应式CSS Grid布局:优化网格项在小屏幕下的堆叠与宽度适配  12306选座怎么选到特殊座位_12306特殊座位选择注意事项  蛙漫2日版入口 WAMAN2(日版)无删减漫画官网链接  知音漫客正版漫画平台_知音漫客官网账号登录  淘宝支付提示失败如何解决 淘宝支付流程优化方法  Yandex搜索引擎官网入口_俄罗斯Yandex免登录一键直达  Bilibili动漫最新防封地址发布-Bilibili动漫2025年最稳正版入口推荐  163邮箱网页版入口导航平台 163邮箱网页版登录入口官网导航  iwriter统一登录平台 iwrite账号密码登录页面  Composer如何解决json扩展缺失的错误  蛙漫画网页版全站入口 蛙漫热门作品免费浏览  Win11怎么合并任务栏图标 Win11开启任务栏合并减少图标占空间【方法】  印象笔记如何设离线包出差查阅_印象笔记设离线包出差查阅【离线阅读】  J*a里如何实现订单支付与库存同步功能_支付库存同步项目开发方法说明  在Runstone环境中高效处理TasteDive API的JSON数据  Win10文件资源管理器“此电脑”分组怎么关 Win10恢复经典视图【技巧】 

搜索