3.7 deno 多线程workers

deno支持 Web Worker API

workers可以在多个线程上运行代码。每个Worker的实例 都在单独的线程上运行,该线程是这个worker专用。

目前,Deno仅支持module类型worker。因此,type: "module"在创建新worker时必须通过该选项。

--location <href>通过在CLI上传递,才支持在main worker中使用相对模块说明符 。不建议将其移植。您可以改用URL构造函数,并import.meta.url轻松为附近的一些脚本创建说明符。但是,专用worker默认情况下具有位置和此功能。

// Good
new Worker(new URL("./worker.js", import.meta.url).href, { type: "module" });

// Bad
new Worker(new URL("./worker.js", import.meta.url).href);
new Worker(new URL("./worker.js", import.meta.url).href, { type: "classic" });
new Worker("./worker.js", { type: "module" });

实例化权限

创建新Worker实例类似于动态导入。因此,Deno需要获得此操作的适当许可。

对于使用本地模块的worker;--allow-read需要许可:

main.ts

new Worker(new URL("./worker.ts", import.meta.url).href, { type: "module" });

worker.ts

console.log("hello world");
self.close();
$ deno run main.ts
error: Uncaught PermissionDenied: read access to "./worker.ts", run again with the --allow-read flag

$ deno run --allow-read main.ts
hello world

对于使用远程模块的worker;--allow-net需要许可:

main.ts

new Worker("https://example.com/worker.ts", { type: "module" });

worker.ts(在https://example.com/worker.ts)

console.log("hello world");
self.close();
$ deno run main.tserror: Uncaught PermissionDenied: net access to "https://example.com/worker.ts", run again with the --allow-net flag
$ deno run --allow-net main.tshello world

在worker中使用Deno

这是不稳定的Deno功能。了解有关不稳定功能的更多信息 。

默认情况下,Deno名称空间在辅助作用域中不可用。

要在创建新工作程序时启用Deno名称空间通过deno.namespace = true选项:

main.js

const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
  type: "module",
  deno: {
    namespace: true,
  },
});
worker.postMessage({ filename: "./log.txt" });

worker.js

self.onmessage = async (e) => {
  const { filename } = e.data;
  const text = await Deno.readTextFile(filename);
  console.log(text);
  self.close();
};

log.txt

hello world
$ deno run --allow-read --unstable main.js
hello world

指定worker权限

这是不稳定的Deno功能。了解有关不稳定功能的更多信息 。

可用于工作程序的权限类似于CLI权限标志,这意味着可以在工作程序API级别上禁用在那里启用的每个权限。您可以在此处找到每个权限选项的更详细说明。

默认情况下,工作程序将从其创建线程中继承权限,但是,为了允许用户限制对此工作程序的访问,我们deno.permissions在工作程序API中提供了该选项。

  • 对于支持精细访问的权限,您可以传递工作人员将有权访问的所需资源的列表,对于只有开/关选项的人员,您可以分别传递true / false。
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
  type: "module",
  deno: {
    namespace: true,
    permissions: {
      net: [
        "https://deno.land/",
      ],
      read: [
        new URL("./file_1.txt", import.meta.url),
        new URL("./file_2.txt", import.meta.url),
      ],
      write: false,
    },
  },
});
  • 粒度访问权限同时接收绝对路径和相对路径作为参数,但是要考虑到相对路径将相对于实例化工作程序的文件而不是工作程序文件当前所在的路径进行解析。
const worker = new Worker(
  new URL("./worker/worker.js", import.meta.url).href,
  {
    type: "module",
    deno: {
      namespace: true,
      permissions: {
        read: [
          "/home/user/Documents/deno/worker/file_1.txt",
          "./worker/file_2.txt",
        ],
      },
    },
  },
);
  • 两者deno.permissions及其子项均支持option "inherit",这意味着它将借用其父级权限。
// This worker will inherit its parent permissions
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
  type: "module",
  deno: {
    namespace: true,
    permissions: "inherit",
  },
});
// This worker will inherit only the net permissions of its parent
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
  type: "module",
  deno: {
    namespace: true,
    permissions: {
      env: false,
      hrtime: false,
      net: "inherit",
      plugin: false,
      read: false,
      run: false,
      write: false,
    },
  },
});
  • 如果未指定deno.permissions选项或其子项之一,则默认情况下会使worker继承。
// This worker will inherit its parent permissions
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
 type: "module",
});
// This worker will inherit all the permissions of its parent BUT net
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
 type: "module",
 deno: {
   namespace: true,
   permissions: {
     net: false,
   },
 },
});
  • 您可以通过传递选项"none" 来一起禁用worker的权限deno.permissions
// This worker will not have any permissions enabled
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
  type: "module",
  deno: {
    namespace: true,
    permissions: "none",
  },
});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 默认情况下,Deno是安全的。因此,除非您专门启用它,否则deno模块不能访问文件,网络或环境。要访问安全敏感的区...
    9e8aeff1c70c阅读 499评论 0 1
  • Deno的目标是使用网络平台API(例如fetch),而不是发明新的专有API。这些API通常遵循规范,并且与Ch...
    9e8aeff1c70c阅读 272评论 0 1
  • 权限可以从运行deno命令时获得。用户代码通常会假定自己拥有一组必需的权限,但是在执行过程中不能保证所授予的权限集...
    9e8aeff1c70c阅读 300评论 0 2
  • 命令行界面 Deno是一个命令行程序。到目前为止,您应该已经熟悉了一些简单的命令,并且已经了解了Shell使用的基...
    9e8aeff1c70c阅读 641评论 0 1
  • Deno支持V8检查器协议[https://v8.dev/docs/inspector]。 可以使用Chrome ...
    9e8aeff1c70c阅读 499评论 0 1