高性能任务容器需兼顾异常冒泡与异步链式取消:1. 基于promise/a+实现链式状态流转与错误冒泡;2. 通过协作式cancellationtoken统一传递中断信号;3. 封装取消感知的微任务调度器;4. 支持取消广播与收敛,确保优雅退出。

要手动实现一个既支持“异常冒泡”又支持“异步链式取消”的高性能任务容器,核心在于两层设计:一是 Promise/A+ 兼容的链式状态流转机制,二是基于协作式取消令牌(CancellationToken)的统一中断信号传递。它不是靠强行终止线程,而是让每个异步节点主动检查、响应并优雅退出。
1. 基于 Promise 的链式结构 + 异常冒泡逻辑
每个 then 必须返回全新 Promise,且内部需封装标准的 resolvePromise 解析逻辑:
- 若 onFulfilled 或 onRejected 抛出异常,新 Promise 立即以该错误 reject,实现“错误沿链向下冒泡”
- 若 onFulfilled 返回值为 Promise(或 thenable),必须递归调用 resolvePromise 处理其终态,不能直接 .then(),否则会丢失 cancel 信号穿透能力
- 默认透传需显式处理:当 onFulfilled 缺失时,应设为
(v) => v;onRejected 缺失时设为(e) => { throw e },确保 reject 不被静默吞掉
2. 取消令牌(CancellationToken)的注入与传播
取消不是附加功能,而是贯穿整个链的“上下文”。关键做法是:
- 每个任务实例持有一个 CancellationToken(可来自 CancellationTokenSource)
- 在 then 创建新 Promise 时,将父级 token 透传给子 Promise,并在执行回调前调用
token.throwIfCancellationRequested() - 所有异步原语(如 delay、fetch 封装、awaitable 操作)都接受 token 参数,在挂起点主动检查——这是协作式取消生效的前提
3. 微任务调度层支持取消感知
标准 queueMicrotask 或 Promise.resolve().then 不带取消能力,需轻量封装:
- 定义
scheduleMicrotask(fn, token),内部先检查token.isCancellationRequested,再决定是否入队 - 所有回调(包括 onFulfilled/onRejected 缓存队列)都走此调度器,确保 pending 状态下注册的回调也能被提前拦截
- 避免使用 setTimeout 或 setImmediate,它们属于宏任务,延迟高且无法被 token 中断
4. 链式取消的触发与收敛
取消操作应具备“向下游广播 + 向上游通知”双重能力:
- 调用
cancel()时,不仅标记当前 token 已取消,还要遍历已注册的子任务 token(如有),触发级联 abort - 每个 Promise 实例维护一个
onCancel回调列表,用于注册清理逻辑(如 abort xhr、close stream) - 当任意一环被取消,整条链应快速收敛:后续未执行的 then 被跳过,已 pending 的回调被丢弃,正在 await 的操作抛出 CancelledError










