Atomics.notify()和waitAsync()不能直接构建跨环境业务状态锁,因二者仅限同一SharedArrayBuffer视图及同一JavaScript Agent内生效,不支持跨进程、跨iframe、跨Worker或浏览器与Node.js互通;需结合postMessage、BroadcastChannel等上层通信机制实现协同。

Atomics.notify() 和 waitAsync() 本身 不能直接构建跨环境的业务状态锁,因为它们仅作用于 SharedArrayBuffer 的同一块内存视图,且要求所有参与者运行在同一个 JavaScript Agent(即同一线程或同一 Worker 环境中),不支持跨进程、跨 iframe、跨服务端(如 Node.js 与浏览器)、甚至跨 Worker 实例的通信——除非你手动桥接底层通信机制。
SharedArrayBuffer 的作用域限制是根本前提
Atomics.waitAsync() 只能监听本地 SharedArrayBuffer 中某个索引位置的变化,Atomics.notify() 也只唤醒同一 buffer 上等待的本地线程。这意味着:
- 浏览器主线程和 Web Worker 可共享 SAB,但需显式传递,且两者属于不同 Agent,waitAsync 不支持跨 Agent 等待(目前规范明确禁止);
- 两个独立的 Web Worker 之间无法直接 notify 对方的 waitAsync,除非它们共享同一个 SAB 并处于同一 Agent 组(实际不可控);
- Node.js 虽支持 SharedArrayBuffer,但其 worker_threads 模块中的 Atomics.waitAsync 仍限于同一线程组内,且与浏览器不互通;
- iframe、Service Worker、WebAssembly 线程等均不构成可互 notify 的统一等待域。
“非阻塞式状态锁”的合理实现路径
若目标是“避免轮询、不阻塞主线程、协调多个并发任务对某业务状态(如订单支付中、配置加载中)的访问”,更可行的方式是结合 Atomics + Promise + 事件分发,而非寄望于跨环境原生 wait/notify:
- 用 SharedArrayBuffer + Atomics 做 轻量级本地状态标记(例如:INT32ARRAY[0] = 1 表示 locked),配合 Atomics.compareExchange 实现无锁设值;
- waitAsync 仅用于当前 Worker 内部的短暂等待(如等待另一同步任务释放锁),并用 .value.then() 接续逻辑,保持非阻塞;
- 跨环境协调交给上层通信机制:postMessage、BroadcastChannel、MessageChannel 或自定义事件总线,由接收方自行决定是否触发本地锁检查;
- 真正“跨环境”的锁语义(如分布式锁)必须依赖外部协调器(Redis、etcd)或带时序保证的消息协议,JS 原生原子操作无法替代。
一个典型协同模式示例(同 Worker 内)
假设你在 Worker 中管理一个配置加载锁,主线程通过 postMessage 请求获取配置,Worker 需避免重复加载:
- 声明 const sab = new SharedArrayBuffer(4); const iv = new Int32Array(sab); // iv[0] 表示 lock 状态
- 收到请求时:if (Atomics.compareExchange(iv, 0, 0, 1) === 0) { /* 未锁定,执行加载 */ } else { /* 已锁定,调用 waitAsync 等待释放 */ }
- 加载完成后:iv[0] = 0; Atomics.notify(iv, 0, 1);
- 等待方:Atomics.waitAsync(iv, 0, 1).value.then(() => { /* 继续处理 */ });
注意:此模式只在当前 Worker 内有效;若主线程也想“等待”,它不能调用 waitAsync(不支持),只能监听 Worker 的 postMessage 回传。
替代方案建议:面向业务场景选型
不要强行用 Atomics 扩展到不支持的边界。根据实际跨环境需求选择:
- 同源多标签页 → 使用 BroadcastChannel 发送 “lock_acquired” / “lock_released” 事件,各页面自行维护本地锁状态;
- 主线程 ↔ Worker → 用 MessageChannel 建立双向通道,Worker 内用 Atomics.waitAsync 做细粒度等待,主线程用 Promise + onmessage 响应;
- 前端 ↔ 后端协作锁 → 前端请求前先 POST /lock?resource=order_123,后端用 Redis SETNX 返回是否获得锁,前端轮询或长连接监听结果;
- 纯前端多模块协同 → 用单例状态机 + Promise 缓存(如:loadConfig() 返回同一个 Promise 实例),天然去重,无需原子操作。
Atomics 是高性能并发原语,不是分布式协调工具。把它用对地方,比试图突破规范边界更可靠。

















