Atomics.load轮询低效,应改用Atomics.wait+Atomics.notify机制:主线程挂起等待、Worker通知唤醒,需满足COOP/COEP响应头、SAB通过transfer传递、状态访问必须用Atomics方法。

直接用 Atomics.load 做轮询不是高效做法,它本身不阻塞也不等待,只是原子读取——频繁调用反而浪费 CPU、掩盖真实同步需求。真正高效的跨线程状态感知,靠的是“条件等待 + 原子通知”,而不是轮询。
为什么不能靠循环调用 Atomics.load
轮询本质是忙等待(busy-waiting):主线程反复执行 Atomics.load(view, 0) 判断状态,即使状态未变也持续占用 CPU 时间片。在高并发或低频更新场景下,这既无必要又低效;还可能因错过瞬时状态变化而逻辑出错(比如刚读到 RUNNING,下一毫秒就变成 DONE,但没监听到跳变)。
正确替代方案:用 Atomics.wait 配合 Atomics.notify
浏览器原生支持的轻量级线程挂起机制,才是高效等待状态变化的正解:
- 主线程调用
Atomics.wait(stateView, 0, STATE_IDLE)—— 当前值等于STATE_IDLE时,线程立即挂起,不消耗 CPU - Worker 完成任务后,执行
Atomics.store(stateView, 0, STATE_DONE),再调用Atomics.notify(stateView, 0, 1) - 主线程被唤醒,此时再用
Atomics.load(stateView, 0)读取最新状态,安全可靠
必须满足的前提条件
这套机制能跑起来,三个硬性条件缺一不可:
- 服务端返回两个响应头:
Cross-Origin-Opener-Policy: same-origin和Cross-Origin-Embedder-Policy: require-corp - SharedArrayBuffer 必须通过
postMessage(..., [sab])的 transfer list 传递给 Worker,不能只传引用 - 所有状态读写必须走
Atomics.load/Atomics.store,绝不能用stateView[0]这类普通访问
一个最小可运行状态等待模式
假设状态视图定义为 const stateView = new Int32Array(sharedBuffer, 0, 1),初始值为 STATE_IDLE:
- Worker 端完成计算后:
Atomics.store(stateView, 0, STATE_DONE); Atomics.notify(stateView, 0, 1); - 主线程等待并响应:
Atomics.wait(stateView, 0, STATE_IDLE); const finalState = Atomics.load(stateView, 0); - 注意:
Atomics.wait返回值是"ok"或"not-equal",不是新状态值,必须再 load 一次

















