在 Chrome 的扩展 Service Worker 中使用 OPFS(原始私有文件系统)

Joh*_*old 6 javascript api google-chrome-extension

我想按照示例来使用这个新的 API 。基本设置没有问题,尽管当我尝试使用createSyncAccessHandle()方法时它立即失败。将其更改为会createAccessHandle()产生相同的结果。我有错误TypeError: fileHandle.createSyncAccessHandle is not a function。这是代码:

const root = await navigator.storage.getDirectory();
const fileHandle = await root.getFileHandle('Untitled.txt', { create: true });
const accessHandle = await fileHandle.createSyncAccessHandle();
Run Code Online (Sandbox Code Playgroud)

有没有办法可以在 chrome 扩展中使用这个 OPFS 功能?它在服务工作者内部以及弹出脚本中都会失败(例如)。

注意:OPFS 的其他功能(如createWritable()/getFile())运行良好。

fra*_*eed 1

OPFS 的一般使用方法

由于 OPFS 是一种系统实现,因此需要了解如何进行低级系统编程,一般来说,您永远不会以高效的方式直接使用 OPFS,而您需要成为操作系统。这意味着您计划任务(又名进程),并且您不会在内核模式下执行它,例如后台工作人员或主窗口。因此,在这两种情况下,您都会为每个任务/进程生成一个工作人员,而不是一个承担所有任务的工作人员。我希望这可以帮助您了解情况并实现您的目标。

模块.js

// worker class
export class OPFSWorker {
    constructor() { 
    const root = await navigator.storage.getDirectory();
    const fileHandle = await root.getFileHandle('Untitled.txt', { create: true });
    const accessHandle = await fileHandle.createSyncAccessHandle();
    }
    onMessage(event) {
        console.log("main to worker", event.data);
        postMessage({ type: "answer", data: "data from worker" });
    }
}

// class to worker
export const workerFromClass = (workerClassRef) => {
    console.log(workerClassRef.name, "to worker");
    const workerFactory = (self, workerClass) => {
        const worker = new workerClass();
        self["onmessage"] = worker.onMessage.bind(worker);
    };

    return new Worker(URL.createObjectURL(new Blob(
        [`${workerClassRef}
        (${workerFactory}) 
        (this,${workerClassRef.name});`],
        {type: "application/javascript"}
    )));

};

// or alternativ export combined 
export const worker = workerFromClass(OPFSWorker);
// Then use worker directly imported.
Run Code Online (Sandbox Code Playgroud)

// 主要的

import { workerFromClass, OPFSWorker } from './module.js';
let worker = workerFromClass(OPFSWorker);

// handle messages from worker
worker.addEventListener(
    "message", (event) => console.log("worker to main", event.data)
);

// send message to worker
let message = { type: "question", data: "data from main" };
console.log("main to worker", message);
worker.postMessage(message);
Run Code Online (Sandbox Code Playgroud)