atomics.waitasync是javascript中唯一不阻塞主线程、基于sharedarraybuffer实现跨线程等待状态更新的原生机制,返回promise使worker或主线程可挂起等待共享内存值变化,需满足sharedarraybuffer、int32array及至少一次atomics.notify调用三项前提。

Atomics.waitAsync 是 JavaScript 中唯一能在不阻塞主线程的前提下、基于 SharedArrayBuffer 实现跨线程等待共享状态更新的原生机制。它返回一个 Promise,让 Worker 或主线程能“挂起等待”某个位置的值变化,而不会冻结 UI 或阻塞事件循环。
前提条件:必须满足的底层约束
使用 Atomics.waitAsync 不是简单调用 API 就行,需同时满足三项硬性要求:
- 共享内存必须是 SharedArrayBuffer 实例(普通 ArrayBuffer 不行);
- 等待的目标视图必须是 Int32Array(仅支持 32 位整数);
- 调用线程必须已通过 Atomics.notify 在同一缓冲区上“注册过唤醒能力”——即该线程此前至少成功执行过一次 Atomics.notify(哪怕通知 0 个等待者),否则会抛出
TypeError: wait not allowed。
典型协作模式:Worker 发布 + 主线程异步等待
常见场景是 Worker 计算完成后更新状态,主线程响应式处理。例如:
AI 舌诊面诊问诊医疗系统 + 诊疗商城系统源码是一套结合 AI 辅助诊断与商品转化的健康类程序,基于浩创云、ThinkPHP(PHP)开发,支持微信服务号与 H5 端,适合做中医舌诊面诊问答、健康建议推送以及配套诊疗商品的运营。
- 主线程创建
sab = new SharedArrayBuffer(4)和view = new Int32Array(sab),初始设view[0] = 0(表示“未就绪”); - 主线程启动 Worker,并立即调用
Atomics.waitAsync(view, 0, 0)—— 等待位置 0 的值从 0 变更(第三个参数是预期旧值); - Worker 完成后执行
Atomics.store(view, 0, 1)再调用Atomics.notify(view, 0, 1)(通知最多 1 个等待者); - 主线程的 Promise 自动 resolve,携带
{ async: true, value: 1 },后续可安全读取新值或触发 UI 更新。
关键细节与避坑提示
实际使用中容易忽略但至关重要的点:
-
waitAsync 不自动重试:如果被通知时值已改变(比如 notify 前被其他线程改写),Promise 仍会 resolve,但
value是当前实际值,不是你期望的“变更后的值”。需要在 then 中校验业务状态是否符合预期; - notify 必须在 waitAsync 调用之后发生:若 notify 先于 waitAsync 执行,等待将永久挂起(无超时机制),因为 JS 没有“唤醒丢失”补偿;
-
不能在非 Worker 线程中对同一视图混用同步 wait:
Atomics.wait(已废弃)和waitAsync不能共存于同一共享位置,否则行为未定义; -
浏览器兼容性需检查:目前仅 Chromium 系(Chrome/Edge/Opera)和 Firefox 支持,Safari 尚未实现,生产环境务必 feature detect:
if (Atomics.waitAsync) { ... }。
替代思路:当 waitAsync 不可用时
若目标环境不支持或需更宽松的语义,可退化为轮询 + postMessage 组合:
- Worker 完成后发
postMessage({ type: 'ready', data }); - 主线程监听 message,用
Atomics.compareExchange原子标记状态,再触发后续逻辑; - 虽非零开销,但在低频更新场景下比密集轮询高效,且完全跨浏览器兼容。










