闭包通过封装原子步骤的上下文、状态与控制信号,配合共享控制器和promise链,实现步骤级中断与恢复。每个步骤为工厂生成的闭包,捕获输入、维护状态、提供execute/pause/resume方法;控制器统一调度生命周期;上下文固化确保恢复精准;abortsignal与挂起检查保障安全中断。

闭包本身不提供中断与恢复能力,但它能可靠固化每个步骤的上下文、状态和控制信号,为“步骤级中断与恢复”提供天然隔离层。关键在于把流程拆成原子步骤,每个步骤由独立闭包封装其参数、执行逻辑、暂停标记和恢复入口,再通过共享控制器协调生命周期。
将流程切分为带状态的闭包步骤
每个异步步骤不应是裸函数,而应由工厂函数生成,捕获自身所需的全部上下文,并维护可变状态:
- 外层函数接收原始输入(如 user.id、order.items)、配置(timeout、retry)和共享控制器引用
- 闭包内定义 let isCompleted = false、let result = null、let error = null、let resumePoint = null
- 返回的对象包含 execute()(执行本步)、pause()(设标志并保存中间态)、resume()(从断点继续)
- 例如:库存校验步骤闭包固定了商品 ID 和预期数量,即使后续订单创建失败,它仍能准确回滚该次扣减
用共享控制器统一管理步骤生命周期
所有步骤闭包都引用同一个轻量控制器对象,实现跨步骤的协同控制:
- 控制器含 { isPaused: false, currentStepIndex: 0, results: [] } 等字段,所有步骤读写同一份状态
- pause() 调用时,控制器设 isPaused = true,当前步骤调用自身的 pause() 方法保存快照(如已查到的库存值)
- resume() 触发后,控制器推进 currentStepIndex,唤醒下一个未完成步骤;若某步需重试,则跳过递增,直接调用其 resume()
- 控制器不持有业务数据,只做调度中枢,避免成为状态污染源
在步骤间固化可恢复的执行上下文
恢复不是从头开始,而是基于上一步输出继续——这依赖闭包对输入/输出的稳定捕获:
- 步骤二的闭包在创建时就捕获步骤一的输出 Promise 或结果对象,而非在执行时动态取值
- 使用结构化克隆或冻结(Object.freeze)保护输入对象,防止外部修改导致恢复时数据错位
- 对需要回滚的操作(如预扣款),闭包提前捕获变更前快照(如 balanceBefore = 100),恢复时可直接还原
- 每个步骤的 resume() 方法只处理自身闭包内已知的断点类型(如 “waiting-for-payment-callback”),不依赖外部传参
配合 Promise 链与中断信号实现安全挂起
挂起必须发生在 Promise 链自然断点处,不能强行终止正在运行的微任务:
- 每个步骤返回的 Promise 在 resolve 前检查控制器 isPaused 状态,为 true 则进入 pending 状态并注册 onresume 回调
- 利用 AbortSignal 注入:步骤执行时传入 controller.signal,fetch 或 setTimeout 内监听 signal.aborted,主动退出并标记中断
- 恢复时重新触发原 Promise 的 resolve 或 reject,保持链式行为不变,下游步骤无需感知中断发生
- 避免在 then 回调里做耗时同步操作,确保挂起点清晰、可预测











