尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

3 个钩子覆盖状态转换生命周期:Workflow 的 on_entry、on_exit、on_transition

3 个钩子覆盖状态转换生命周期:Workflow 的 on_entry、on_exit、on_transition 3 个钩子覆盖状态转换生命周期Workflow 的 on_entry、on_exit、on_transition【免费下载链接】uBlockuBlock Origin - An efficient blocker for Chromium and Firefox. Fast and lean.项目地址: https://gitcode.com/GitHub_Trending/ub/uBlockRuby 状态机 Workflow 把钩子函数挂在状态转换的关键节点上on_entry 进状态、on_exit 离状态、on_transition 跟全程3 个钩子就能覆盖一次状态转换的完整生命周期。 先看全景一次状态转换里发生了什么先别急着写钩子。把 pending → paid 这样一次转换拆成 5 个站点顺序是固定的钩子执行顺序表顺序站点发生时机一句话说明1before_transition转换开始前做校验拦下就终止转换不会发生2on_transition转换进行中不关心具体状态只记录从哪到哪3on_exit离开旧状态时收尾释放资源、存状态快照4on_entry进入新状态时初始化设默认值、发通知5after_transition转换完成后写日志、埋点可以把状态对象想象成流水线上的工单每过一个工位就被处理一次。on_exit 和 on_entry 分别挂在旧、新两个状态的工位上on_transition 则是架在整条线之上的摄像头每张工单经过都拍一帧。这个顺序在 gem 源码lib/workflow.rbL110–L129 中有明确实现也是 Ruby 状态机钩子执行顺序的标准答案。所以5 个工位的先后是固定的先记住这张顺序表再谈每个钩子具体干什么。 三个钩子的职责边界一张表讲清楚钩子触发时机典型职责参数签名一句比喻on_entry进入新状态时状态级初始化数据、发通知、启动后续流程(prior_state, event, *args)入口卡到新工位先打卡、领物料on_exit离开旧状态前状态级资源释放、离开校验、状态快照(new_state, event, *args)出口卡离岗时清点工具、签退on_transition转换进行中工作流级全局审计、转换跟踪、耗时统计(from, to, event, *args)摄像头每张工单经过都留一帧on_entry 和 on_exit 挂在状态上只在特定状态生效on_transition 挂在工作流上定义一次所有转换通用。选哪个先问一句这段逻辑只属于某个状态还是对所有转换都成立所以状态专属逻辑放 on_entry / on_exit跨状态通用逻辑放 on_transition。 参数速查表三个钩子各收什么钩子参数含义on_entryprior_state转换前的旧状态on_entrytriggering_event触发本次转换的事件on_entry*args事件方法附带的额外参数on_exitnew_state即将进入的新状态on_exittriggering_event触发本次转换的事件on_exit*args事件方法附带的额外参数on_transitionfrom源状态on_transitionto目标状态on_transitionevent触发本次转换的事件on_transition*args事件方法附带的额外参数on_entry 用法示例里最常见的组合是 prior_state *args既知道工单从哪来又拿得到业务参数。这些签名定义在lib/workflow.rbL214–L232。所以三个钩子的参数结构几乎一致差别只在另一个状态指的是旧状态prior_state还是新状态new_state。 贯穿案例给订单系统装上钩子订单钩子案例4 个状态的订单3 个钩子各就各位class Order include Workflow workflow do initial_state :pending state :pending, on_exit: -(s, e) { verify_stock! } # 出口卡 state :paid, on_entry: -(s, e) { charge_card! } # 入口卡 state :shipped, on_entry: -(s, e) { notify_warehouse! } state :cancelled, on_entry: -(s, e) { refund! } # ... pay / ship / cancel 等事件声明略 on_transition { |from, to, ev, *args| AuditLog.record(from, to, ev, args) } # 摄像头 end endpending 的出口卡在离开前确认库存paid 的入口卡完成扣款cancelled 的入口卡触发退款。审计日志不写进任何一个状态统一由 on_transition 兜底——以后新增 shipped → returned 之类的转换审计代码一行不用动。所以钩子之间互不侵入新增转换不需要改旧钩子。✅ 避坑检查清单✅ 一个钩子只干一件事扣款和发通知拆开写排查时不会两件事纠缠在一起。✅ 业务参数走 *args 显式传入钩子里不用翻全局对象也方便单独测试。✅ 钩子保持幂等消息可能重投写日志、发通知前先判重。✅ 校验放在转换发生前在 before 阶段拦下就不会出现改了一半的状态。⚠️ 别在 on_entry 里再触发状态转换会递归钻进流水线调用栈容易失控。⚠️ 别依赖 on_exit 留下的临时变量给 on_entry 用两者之间状态正在切换顺序一变就埋雷。⚠️ 耗时操作别塞进 before_transition它每次转换都要跑会拖慢整条流水线。⚠️ on_transition 只放审计和日志业务分支逻辑还是放回具体状态里。所以✅ 是写法习惯⚠️ 是容易写炸的地方动手前过一遍能省不少排查时间。 上手建议先跑一次真实转换把 5 个工位的执行顺序亲眼确认一遍再往里填业务逻辑。想看调度细节翻 gem 源码lib/workflow.rbL110–L129 是转换主流程L214–L232 是钩子参数拼装。状态变多以后把 on_transition 的审计输出接到日志系统比在每个状态里手写日志省心。所以先挑一条业务状态流试点钩子用熟了再往复杂场景上加。【免费下载链接】uBlockuBlock Origin - An efficient blocker for Chromium and Firefox. Fast and lean.项目地址: https://gitcode.com/GitHub_Trending/ub/uBlock创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表