atomics.notify 必须与 atomics.wait 配对使用且仅在 worker 线程生效;常见无效原因包括:主线程调用、sharedarray 非 int32array、wait 前值已变更、跨域隔离未配置或 notify 的 count 参数过小。

Atomics.notify 不能单独“触发唤醒”,它必须和 Atomics.wait 配对使用,且只能在 Worker 线程中生效;主线程调用会直接报错。
为什么 Atomics.notify 没反应?常见错误现象
你写了 Atomics.notify(sharedArray, 0),但等待的线程没醒来——这通常不是 notify 写错了,而是前置条件没满足:
-
Atomics.wait必须已在另一个 Worker 线程中执行并处于挂起状态(即:视图是Int32Array、索引值未变、超时未到) - 主线程里调用
Atomics.wait或Atomics.notify:直接抛TypeError: wait not allowed on main thread - 传入的
sharedArray是Uint8Array或Float64Array:报RangeError: view is not an Int32Array - 等待前已修改过该位置的值(比如先
sharedArray[0] = 1,再Atomics.wait(sharedArray, 0, 0)):函数立刻返回"not-equal",根本没挂起,notify 自然无效
如何正确配对 wait/notify 实现异步唤醒
核心逻辑是“条件等待 + 显式通知”,不是定时唤醒。典型场景:Worker A 处理完一批数据后,通知 Worker B 开始消费。
- 共享内存必须用
Int32Array视图(哪怕你只传标志位):const sab = new SharedArrayBuffer(4); const flag = new Int32Array(sab); flag[0] = 0; - 等待方(Worker B)写成:
Atomics.wait(flag, 0, 0);—— 表示“只要 flag[0] 还是 0,就挂起” - 唤醒方(Worker A 或主线程)改值并通知:
Atomics.store(flag, 0, 1); Atomics.notify(flag, 0, 1);(store确保值已更新,notify唤醒最多 1 个等待者) - 注意
Atomics.notify返回值是实际被唤醒的线程数,可用于调试:const woken = Atomics.notify(flag, 0); console.log(`woken ${woken} threads`);
跨域隔离配置不到位,notify 根本无法启用
浏览器默认禁用 SharedArrayBuffer,所以即使代码全对,new SharedArrayBuffer(4) 也会直接抛 TypeError: SharedArrayBuffer is not enabled。
- 服务端必须返回两个响应头:
Cross-Origin-Opener-Policy: same-origin和Cross-Origin-Embedder-Policy: require-corp - 加载 Worker 脚本时需带
crossorigin属性:<script crossorigin src="worker.js"></script>或new Worker('worker.js', { type: 'module' });(模块 Worker 默认要求 CORP) - 本地开发别用
file://协议打开 HTML,必须走http://localhost或https://(例如npx serve)
notify 的 count 参数容易被忽略的实际影响
Atomics.notify(typedArray, index, count) 的 count 是“最多唤醒几个等待者”,不是“唤醒所有”。如果多个 Worker 同时在等同一个位置,不传或传 1 就只唤醒一个。
- 想广播唤醒全部等待者:传
Infinity或一个足够大的数(如100) - 传
0:不唤醒任何人(合法但无意义) - 如果等待者数量超过
count,多余者继续挂起,直到下一次notify - 这个机制常用于实现“信号量”或“生产者-消费者队列”的批量唤醒逻辑
真正卡住的地方往往不在 notify 本身,而在于 wait 是否成功挂起、共享内存是否被正确传递、以及跨域策略是否生效——三者缺一不可。尤其要注意,Atomics.wait 不是轮询,它一旦挂起,就完全交由内核调度,期间 CPU 零消耗;但这也意味着,如果 notify 漏发或发早了,线程可能永远等下去。











