OPFS在Worker中不支持createSyncAccessHandle,该API已被Chrome等浏览器废弃;Worker只能通过主线程传递FileSystemFileHandle,再异步调用createWritable()并确保await close()来安全写入。

createSyncAccessHandle 不能在 Worker 中使用,它根本不存在于当前任何浏览器的 OPFS 实现中。
这是个高频误解:很多人看到 FileSystemSyncAccessHandle 这个类名,就以为能调用 createSyncAccessHandle() 方法同步读写。但事实是——该 API 已被 Chrome 团队正式废弃(2023 年底移除),且从未在 Worker 环境中可用。所有基于它的代码现在会直接抛出 TypeError: root.createSyncAccessHandle is not a function。
createSyncAccessHandle 为什么被废弃?
- 它依赖底层线程安全的同步文件 I/O 原语,在 JS 单线程模型 + Web 安全沙箱下难以可靠实现;
- 同步阻塞行为与 Worker 的“避免主线程卡顿”设计目标冲突,反而容易引发死锁或调度异常;
- 所有主流引擎(Chrome 122+、Edge 122+)已完全删除该方法,连 polyfill 都无法模拟。
Worker 中真正可行的 OPFS 文件读写方式
Worker 内只能用异步句柄链路,但可以做到“近似同步语义”的可控顺序:
- 必须从主线程传入一个
FileSystemDirectoryHandle或FileSystemFileHandle(通过postMessage()传递可序列化的 transferable 句柄); - Worker 中不能调用
window.storage.getDirectory()—— 它只在主线程安全上下文有效; - 所有操作必须 await,不可用
sync模式。
// 主线程
const root = await window.storage.getDirectory();
const file = await root.getFileHandle('cache.bin', { create: true });
worker.postMessage({ type: 'init', handle: file }, [file]);
// Worker 内
self.onmessage = async ({ data }) => {
if (data.type === 'init') {
const file = data.handle; // 已 transfer 过来的 FileSystemFileHandle
const writable = await file.createWritable(); // ✅ 唯一合法入口
await writable.write(new Uint8Array([1, 2, 3]));
await writable.close(); // ⚠️ 漏掉这句,数据不会落盘
}
};
容易踩的坑
-
FileSystemFileHandle不能直接postMessage,必须作为 transferable 第二个参数传入:worker.postMessage(..., [handle]),否则报DataCloneError; - Worker 中调用
file.createWritable()后,若未await close()就结束 Worker,文件内容可能为空或截断; - 不支持
read()同步返回;要读取,得用file.getFile()→arrayBuffer(),仍是异步; - Firefox / Safari 当前不支持 OPFS,Worker 场景下无降级路径,需提前检测:
if (!('storage' in self && 'getDirectory' in self.storage)) { /<em> fallback </em>/ }。
OPFS 在 Worker 中的核心限制不是“怎么同步”,而是“它天生就不允许同步”——接受这个前提,才能写出稳定代码。
立即学习“前端免费学习笔记(深入)”;



















