Worker 之 SharedWorker 初探 —— 多个页面间共享资源

2025年07月25日 Tags: Js


实现多个 tab 页面间的通信方式有很多种,比如:

Web Worker

特点:

(1)worker 会在一个单独的线程中执行,不会阻塞主线程,因此可以将包含大量计算的代码交给 worker 执行。

(2)worker 有自己的上下文,因此无法访问 Window、DOM 等。

(3)消息机制:通过自身的 postMessage() 方法和 onmessage 事件处理程序,来处理和主线程之间的数据传递。也可以通过 MessageChannel 与主线程进行通信。(注:传递的数据包含在 message 事件的 data 属性中,这个过程数据是被复制而不是被共享的。

通常所说的 Web Worker 指的是 Dedicated Worker,其他还有 Shared Worker(共享),Service Worker(缓存)、Audio Worker(处理音频)。

这里主要对 Shared Worker 进行一个简单的探索,示例一个小 Demo,因为官方的 Demo(运行共享型 worker)没什么卵用。

Shared Worker

相关链接:

SharedWorker 是一种在多个浏览器上下文中共享脚本的机制。

示例

这里我们有两个页面 index1.htmlindex2.html,它们都使用了同一个 worker.js 文件。

在 index1 页面中输入两个数字,然后进行乘法运算,之后将运算结果发送给 index2 页面,将计算的结果呈现在页面上。(计算过程可以移到 worker.js 中)

<-- index1.html -->
<label for="number1">number1</label>
<input type="number" id="number1" />
<label for="number2">number2</label>
<input type="number" id="number2" />
<button>Send</button>
// index1.js
let number1 = 0, number2 = 0;
const input1 = document.getElementById("number1");
const input2 = document.getElementById("number2");
const button = document.querySelector("button");
input1.addEventListener("change", (e) => {
  number1 = e.target.value;
});
input2.addEventListener("change", (e) => {
  number2 = e.target.value;
});

var myWorker = new SharedWorker("worker.js");
myWorker.port.start();
button.addEventListener("click", () => {
  myWorker.port.postMessage([number1, number2]);
});
<-- index2.html -->
<span id="shared"></span>
// index2.js
const oSpan = document.querySelector("#shared");
var myWorker = new SharedWorker("worker.js");
myWorker.port.start();
myWorker.port.onmessage = (e) => {
  oSpan.textContent = e.data
}
// worker.js
const portsSet = new Set(); // worker 连接的端口收集

onconnect = (event) => {
  const port = event.ports[0];
  portsSet.add(port);
  port.onmessage = function (e) {
    const workerResult = e.data[0] * e.data[1];
    portsSet.forEach((p) => {
      // 发送信息给 index2
      if (p !== port) {
        p.postMessage(workerResult);
      }
    });
  };
};

浏览器打开 index1.html,在界面上分别输入数字 3 和 4 :

Description

这时,我们可以看到 index2 页面上显示计算结果为 12 。

← 上一篇: 手把手实现 Select 组件

下一篇: → 导入并导出目录下模块文件的方法&使用桶文件的后果