Atomics.wait() 是同步阻塞操作,适用于 Worker 内部基于 SharedArrayBuffer 的高精度时序同步,需跨源隔离、主线程创建 SAB、统一视图类型等前提,核心是“条件等待+原子校验”,须循环检查防虚假唤醒并设超时。

Atomics.wait() 本身是同步阻塞操作,不能直接用于“异步逻辑执行时序同步”——它会让调用它的 Worker 线程暂停,直到被 notify 或超时。所谓“高精度时序同步”,关键不在于等待本身有多准,而在于所有参与方对共享状态的读取、判断、等待和唤醒是否严格按原子语义协同。它适用于 Worker 内部需要精确响应某个共享变量变化的场景,比如任务栅栏、锁等待、信号量计数归零等。
必须满足的运行前提
缺一不可,否则会抛错或行为未定义:
- 运行环境必须启用跨源隔离:服务端响应头需包含 Cross-Origin-Opener-Policy: same-origin 和 Cross-Origin-Embedder-Policy: require-corp
- 不能使用
file://协议打开页面;本地开发需启动 HTTP 服务(如python3 -m http.server 8000) - SharedArrayBuffer 必须由主线程创建并传入 Worker(使用
postMessage(sab, [sab])),确保传输的是底层缓冲区引用 - 所有 Worker(及主线程,如参与通知)必须用完全相同的视图类型访问,例如统一使用
new Int32Array(sab),偏移和字节序必须一致
实现时序同步的核心模式:条件等待 + 原子校验
Atomics.wait() 不是轮询,也不是事件监听。它只在你明确指定“当前值等于某预期值”时才挂起线程。因此,时序控制依赖于你如何设计这个“预期值”与“触发变更”的配合逻辑。
AI 舌诊面诊问诊医疗系统 + 诊疗商城系统源码是一套结合 AI 辅助诊断与商品转化的健康类程序,基于浩创云、ThinkPHP(PHP)开发,支持微信服务号与 H5 端,适合做中医舌诊面诊问答、健康建议推送以及配套诊疗商品的运营。
- 用一个整数位置(如索引 0)作为同步信号位,初始设为 0
- 等待方先用
Atomics.load(view, 0)确认当前值是 0,再调用Atomics.wait(view, 0, 0, timeoutMs)—— 第三个参数必须严格匹配当前值,否则立即返回"not-equal" - 通知方在准备就绪后,用
Atomics.store(view, 0, 1)修改值,再立刻调用Atomics.notify(view, 0, 1)唤醒一个等待者 - 等待方被唤醒后,必须再次检查
view[0] === 1(防虚假唤醒),确认后再执行后续逻辑,才能保证时序不乱
避免时序漂移与死锁的关键细节
精度损失往往来自逻辑疏漏,而非 API 本身:
- 永远在循环中调用 wait:返回 "ok" 只表示被唤醒,不代表条件已真正满足;返回 "timed-out" 则需决定重试或报错
- 超时参数不能省略:
Atomics.wait(view, 0, 0, 5000)设置 5 秒上限,防止因通知遗漏导致永久阻塞 - 不要混用
Atomics.wait()和Atomics.waitAsync()在同一位置:前者阻塞线程,后者返回 Promise,二者唤醒机制不互通 - 若需多个 Worker 按顺序依次执行(如流水线阶段),可用递增计数器代替布尔信号,每个 Worker 等待自己的目标值,通知方每次只 notify 一个
典型适用场景示例
以下不是伪代码,而是可落地的逻辑骨架:
-
任务完成栅栏:3 个 Worker 各自处理一批数据,完成后都对共享计数器
doneCount执行Atomics.add(view, 1, 1);第 4 个 Worker 循环Atomics.wait(view, 1, 3),等待计数器达到 3,再开始汇总 -
双阶段初始化同步:Worker A 初始化资源后设
view[0] = 1并 notify;Worker B 在启动时先Atomics.wait(view, 0, 0),被唤醒后检查view[0] === 1成立,才开始加载依赖该资源的模块 -
带优先级的信号响应:用不同索引位代表不同事件(如
view[0]是数据就绪,view[1]是中断请求),Worker 可按需选择等待哪个位置,实现轻量级调度

















