异步状态机中错误应作为预设迁移边而非异常,每个异步动作需定义成功与失败双路径,error 状态须携带上下文并提供 RETRY/CANCEL/REPORT 等明确退出机制,配合防护避免重复触发。

JavaScript 中异步状态机管理复杂流程的错误跳转,核心不是“捕获后跳”,而是“定义好失败路径并让状态自动走过去”。它把错误当作一种合法状态迁移条件,而非需要层层 try/catch 的异常。
错误必须成为状态图中的一条明确边
在状态机设计里,error 不该是意外中断,而应是预设的、可到达的状态节点。比如 WiFi 配网流程中,connecting → error 是一条受控迁移,由连接超时或认证失败等具体条件触发,而不是未处理的 Promise reject 导致整个机器卡死或崩溃。
- 每个可能出错的异步动作(如 API 调用、动画播放)都对应一个“成功→目标状态”和一个“失败→error 或其他恢复态”的双路径
- 避免在 entry/invoke 中 throw 错误;改用 resolve({ type: 'FAILURE', code: 'TIMEOUT' }) 或直接返回 rejected Promise,由状态机统一收口到 error 状态
- error 状态本身应携带上下文(如错误码、重试次数),便于 UI 展示或决策是否自动重试
Promise reject 自动触发失败迁移
使用 javascript-state-machine 或 XState 类库时,在生命周期钩子(如 onEnter、onTransition)中返回被 reject 的 Promise,会中断当前转换,并进入预设的错误处理路径——例如调用 failTransit 后跳转至 error 状态,或触发 onTransitionError 回调。
- 例如:进入
connecting状态时发起 fetch 请求,若 Promise 被 reject,状态机不会停留在 connecting,也不会静默失败,而是立刻转向 error - reject 值会被透传为 event.data,可用于 error 状态下的 action 判断(如 code === 'NETWORK' 就显示重连按钮,code === 'AUTH' 就跳登录页)
- 注意不要漏掉 catch —— 若 Promise 内部已 .catch() 却没 re-throw,状态机将收不到 reject,导致转换悬停或误入成功路径
error 状态要提供明确退出机制
error 不是终点,而是中转站。它必须支持用户可操作的恢复事件,如 RETRY、CANCEL、REPORT,并定义对应迁移:
-
error → connecting(retry,重置计数器后重试) -
error → idle(cancel,清空上下文,回到初始态) -
error → reporting(report,启动日志上报流程,完成后自动回 idle) - 禁止从 error 直接跳业务主流程(如 error → connected),必须经校验或重试后才允许
避免错误被吞掉或重复触发
真实场景中,用户可能在请求进行中连续点击“重试”,或网络恢复后多个 pending 请求同时 resolve,造成状态混乱。需配合防护机制:
- 在 error 状态下禁用除 RETRY/CANCEL 外的所有事件(通过 guard 条件或 UI 层 disable)
- 对异步任务做 cancelable 封装(如用 AbortController),在离开 error 或收到新事件前主动中止旧请求
- 使用 context 记录 pending 任务 ID,确保 resolve/reject 只影响当前有效转换,旧响应丢弃
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











