中断与 abort
AFSM 支持中断进行中的中间态(MiddleState)。
abortAction
@ChangeState 的 opt.abortAction 用于中断指定 action 的中间态:
class Player extends FSM { @ChangeState(FSM.INIT, 'started', { abortAction: undefined }) async start() { await longRunning() // 期间状态是 'starting' (MiddleState) }
@ChangeState('started', 'stopped', { abortAction: 'start' }) async stop() { // 如果当前正处在 'starting' 中间态,会先调用 middle.abort(fsm) }}调用 stop() 时,如果当前正处在 action='start' 的 MiddleState:
middle.abort(fsm)被调用- 设置
middle.aborted = true setState(oldState, new Error("action 'start' aborted"))— 状态回到start之前的旧状态stop()自身的from校验会失败(因为状态已回到start之前,可能不满足'started')
from: [] 自动中断
from: [](任意状态)会自动中断进行中的中间态:
@ChangeState([], 'reset')async reset() {}无论当前处于什么中间态,都会先被中断(middle.abort(fsm)),然后强制迁移到 reset。
MiddleState.abort
class MiddleState { aborted: boolean = false abort(fsm: IFSM): void}abort(fsm):
this.aborted = truesetState.call(fsm, this.oldState, new Error("action '{action}' aborted"))- 状态回到
oldState,发出stateChanged事件(带错误)
中断后,原方法若仍在执行,其 success 回调会检查 middle.aborted:
const success = (result: any) => { fsm[cacheResult] = result if (!middle.aborted) { // 若已中断,不切到 to setState.call(fsm, to) opt.success?.call(this, fsm[cacheResult]) } return result}注意:abort() 不会取消原方法的执行(它无法取消 Promise)。它只是阻止状态切到 to,并回滚到 oldState。原方法若持有资源,需要自行清理。
监听中断
中断会触发 stateChanged 事件,err 参数携带 Error("action '...' aborted"):
obj.on(FSM.STATECHANGED, (newState, oldState, err) => { if (err && err.message.includes('aborted')) { console.log('被中断:', err.message) }})示例场景
- 用户点击「停止」时中断进行中的「开始」操作
- 网络断开时强制重置(
from: []) - 切换页面时取消未完成的请求