本文档介绍了 Deno 的 Web Worker 实现,包括 worker 的创建、消息传递、隔离机制以及通过 worker_threads 实现的 Node.js 兼容性。Web Worker 提供了一种在并行线程中运行 JavaScript 代码并通过结构化通信通道进行交互的方式。
有关更广泛的运行时架构信息,请参阅 运行时架构。有关权限和安全性的详细信息,请参阅 权限系统。
Deno 的 Web Worker 实现由多个层组成,这些层协同工作,提供具有结构化通信的隔离 JavaScript 执行上下文。
Worker 创建和管理流程
来源:runtime/ops/worker_host.rs44-260 runtime/js/11_workers.js80-138 ext/web/13_message_port.js50-88
Worker 创建过程涉及从 JavaScript API 调用到线程启动的多个步骤。
| 组件 | 位置 | 目的 |
|---|---|---|
Worker 类 | runtime/js/11_workers.js80-310 | 用于 worker 创建的 JavaScript API |
op_create_worker | runtime/ops/worker_host.rs144-260 | 用于启动 worker 的 Rust 操作 |
CreateWebWorkerArgs | runtime/ops/worker_host.rs35-44 | Worker 创建参数 |
WorkersTable | runtime/ops/worker_host.rs85 | 活动 worker 管理 |
Worker 创建过程同时处理经典的 (importScripts) 和模块 worker,具有不同的初始化路径。
import 加载 ES 模块。importScripts("#") 占位符和同步 fetch 来加载脚本。来源:runtime/ops/worker_host.rs144-260 runtime/js/11_workers.js94-138 runtime/ops/web_worker/sync_fetch.rs85-200
Web Workers 通过基于 MessagePort 通道的结构化消息传递系统进行通信。
消息传递系统支持结构化克隆和可转移对象。
| 消息类型 | 处理 | 位置 |
|---|---|---|
| 结构化数据 | core.serialize() / core.deserialize() | ext/web/13_message_port.js436-438 |
| MessagePorts | 在上下文之间转移所有权 | ext/web/13_message_port.js446-459 |
| ArrayBuffers | 分离并转移 buffer 所有权 | ext/web/13_message_port.js460-468 |
来源:ext/web/13_message_port.js406-475 ext/web/message_port.rs54-101 runtime/ops/web_worker.rs31-54
Deno 支持两种类型的 Web Workers,具有不同的执行模型。
| 功能 | 模块 Worker | 经典 Worker |
|---|---|---|
| 模块系统 | ES 模块 (import) | importScripts() |
| 脚本加载 | 异步模块解析 | 通过 op_worker_sync_fetch 进行同步 fetch |
| 权限 | 继承或受限 | 继承或受限 |
| JavaScript 上下文 | 现代 ES 环境 | 兼容旧版的环境 |
每个 worker 都在一个单独的线程中运行,并具有:
来源:runtime/ops/worker_host.rs172-181 runtime/permissions.rs1-198 runtime/js/11_workers.js94-138
Workers 拥有一个双通道通信系统,用于消息和控制事件。
控制系统通过以下方式管理 worker 的生命周期:
ErrorEvent 的形式冒泡到宿主。来源:runtime/js/11_workers.js185-218 runtime/ops/worker_host.rs312-352 runtime/js/11_workers.js164-183
Deno 通过 polyfills 提供 Node.js worker_threads 兼容性。
| API | 实现 | 目的 |
|---|---|---|
Worker 类 | ext/node/polyfills/worker_threads.ts91-330 | Node.js 兼容的 worker 创建 |
parentPort | ext/node/polyfills/worker_threads.ts360-471 | Worker 与父级之间的通信 |
workerData | ext/node/polyfills/worker_threads.ts336-400 | 传递给worker的初始数据 |
MessageChannel | ext/node/polyfills/worker_threads.ts514-523 | Node.js 风格的消息通道 |
Node.js 兼容层将 Web Workers 适配为匹配 Node.js API
threadId、resourceLimitsworkerData 属性处理初始数据传递来源: ext/node/polyfills/worker_threads.ts91-660 tests/unit_node/worker_threads_test.ts24-433