SharedArrayBuffer 必须通过 postMessage 的 transfer 选项转移所有权,不可直接赋值或普通传输;转移后原线程引用失效,跨线程同步须用 Atomics,且依赖 Cross-Origin 隔离(COEP/COOP)响应头。

SharedArrayBuffer 不能直接在主线程与 Worker 之间“传递”,只能通过 postMessage() “转移”——即移交所有权,移交后原线程不能再访问该缓冲区。这是最常被误解的第一步。
为什么直接赋值或普通 postMessage 不行
SharedArrayBuffer 是可转移对象(transferable),类似 ArrayBuffer,但语义更严格:它不支持拷贝,也不支持跨线程共享引用。如果你写 worker.postMessage({ buf: sharedBuf }) 而没加 transfer 选项,浏览器会抛出 DataCloneError: SharedArrayBuffer can't be cloned。
常见错误现象:
- 控制台报错
DataCloneError,且 Worker 收不到消息 - 主线程仍尝试读写
sharedBuf,结果静默失败或触发TypeError - Worker 内解构得到
buf为undefined,因为没正确转移
正确转移 SharedArrayBuffer 的写法
必须显式将 SharedArrayBuffer 实例放入 transfer 数组,且仅能转移一次。主线程移交后,自身持有的引用自动变为 null(实际是 detached 状态)。
立即学习“前端免费学习笔记(深入)”;
示例(主线程):
const sab = new SharedArrayBuffer(1024);
const int32 = new Int32Array(sab);
// 写入初始值
Atomics.store(int32, 0, 42);
const worker = new Worker('worker.js');
worker.postMessage({ cmd: 'init', buf: sab }, [sab]); // ✅ 关键:[sab] 在 transfer 列表中
Worker 中接收:
self.onmessage = function(e) {
const { cmd, buf } = e.data;
if (cmd === 'init' && buf instanceof SharedArrayBuffer) {
const view = new Int32Array(buf); // ✅ 可安全构造视图
console.log(Atomics.load(view, 0)); // 输出 42
}
};
跨线程同步必须用 Atomics
SharedArrayBuffer 本身只是内存块,不提供同步机制。若主线程和 Worker 同时读写同一位置(比如 int32[0]),结果未定义——可能丢失更新、读到撕裂值(torn read)。必须用 Atomics 原子操作。
典型使用场景:
- Worker 循环轮询某个标志位:
while (Atomics.load(flagView, 0) === 0) Atomics.wait(flagView, 0, 0) - 主线程通知 Worker 开始工作:
Atomics.store(flagView, 0, 1); Atomics.notify(flagView, 0) - Worker 向主线程回传计算结果:
Atomics.store(resultView, 0, 123),主线程用Atomics.load读取
注意:Atomics.wait() 和 Atomics.notify() 要求视图类型为 Int32Array 或 BigInt64Array,其他类型会抛 TypeError。
Cross-Origin 隔离是硬性前提
现代浏览器(Chrome 92+、Firefox 93+)强制要求页面启用 crossorigin 隔离才能创建 SharedArrayBuffer。否则构造会静默失败或抛 ReferenceError: SharedArrayBuffer is not defined。
必须同时满足:
- 服务器响应头包含
Cross-Origin-Embedder-Policy: require-corp - 服务器响应头包含
Cross-Origin-Opener-Policy: same-origin - HTML 中的
<script>、<iframe>等资源加载需带crossorigin属性(如<script crossorigin src="main.js">)
本地开发时 file:// 协议不支持,必须用 http:// 或 https:// 服务启动(例如 npx serve 或 VS Code Live Server)。
最容易被忽略的是:即使代码逻辑全对,只要缺少 COEP/COOP 响应头,SharedArrayBuffer 就不可用——它不会报错提示缺头,而是让构造函数返回 undefined 或直接不可访问。检查 typeof SharedArrayBuffer 是第一道验证门槛。



















