Web Worker内部不能直接访问DOM,但支持Promise、fetch等异步API,可构建线程隔离的Promise队列,实现无UI阻塞的并发控制与纯净逻辑调度。

Web Worker 内部不能直接使用 DOM 相关 API,但完全支持 Promise、fetch、setTimeout、IndexedDB 等异步能力——这为在后台线程中构建独立、安全、高可控的 Promise 队列提供了坚实基础。关键在于:把并发控制逻辑从主线程剥离,交由 Worker 专注调度,既避免阻塞 UI,又实现真正的线程级隔离控流。
为什么要在 Worker 里做 Promise 队列?
主线程负责渲染和交互,Worker 负责计算与调度,二者天然解耦。将 Promise 队列放进 Worker,带来三重优势:
- 不抢主线程资源:大量 fetch 或数据预处理不会触发页面卡顿或输入延迟
- 无 DOM 干扰风险:队列内部无法误操作 document 或触发 layout,逻辑更纯净
- 通信即契约:主线程只发任务描述(如 { url: "...", timeout: 5000 }),Worker 返回结构化结果,状态不共享、无竞态
Worker 内部队列核心结构(轻量版)
不需要复杂类封装,一个闭包 + 两个数组就能跑起来:
- pendingTasks:存储未执行的任务函数(每个返回 Promise)
- runningTasks:记录当前正在 resolve/reject 的 Promise 数量
- maxConcurrent = 4:默认限制,可由主线程通过 message 动态调整
每次收到新任务,先 push 到 pendingTasks;再检查 runningTasks.length
支持所有权转移的大体积数据流转
当队列要处理 ArrayBuffer、图像像素数据等大对象时,深拷贝代价高。Worker 完全支持 Transferable:
- 主线程调用
postMessage({ type: 'enqueue', task: imageData }, [imageData.buffer]) - Worker 收到后,
imageData.buffer已 detached,可直接用于 canvas 处理或编码 - 结果回传时同样用 transfer,避免二次拷贝
这种“零拷贝调度”让图像批量压缩、音视频元数据提取等场景真正具备生产级吞吐能力。
错误隔离与重试策略下沉
主线程不该替 Worker 做重试决策。建议在 Worker 内部封装带退避的 fetch 封装器:
- 单个任务失败时,自动按指数退避(1s → 2s → 4s)重试最多 3 次
- 连续 5 次失败触发降级:切换备用接口或标记该任务为 skip
- 所有异常统一格式返回:
{ id, status: 'failed', reason: 'network_timeout', retry: 2 }
主线程只需监听 message,按 type 区分 success / failed / progress,无需感知底层重试逻辑。

















