Web Worker: Shared Worker的使用
Web Worker: Shared Worker的使用
参考资料:
- JavaScript高级程序第四版
- https://juejin.cn/post/7064486575916187656
- https://juejin.cn/post/6844904198639714311 [你不知道的Service Worker]
- https://juejin.cn/post/6963519363492085790 [sharedWorker 实现多页面通信]
一、概述
shared worker,是一种共享的工作者线程,也就是说可以在不同的页面之间(iframe,tab页等场景)访问同一个工作者线程(前提仍然是必须同源,即协议、主机、端口号必须一致)。
shared Worker的一些特点:
-
同标识符的实例只会创建一个 sharedWorker,其他页面再使用同样的脚本创建sharedWorker,会复用已创建的 worker,这个worker由几个页面共享。这里的相同标识符指的是共享者线程会解析来自脚本的URL,工作者线程名称和文档源,只有这三个属性保持一致才会认定是同一个工作者线程。
// 实例化一个共享工作者线程 // - 全部基于同源调用构造函数 // - 所有脚本解析为相同的 URL // - 所有线程都有相同的名称 new SharedWorker('./sharedWorker.js'); new SharedWorker('./sharedWorker.js'); new SharedWorker('./sharedWorker.js');
下面这种情况也只会实例化一个共享工作者线程
// 实例化一个共享工作者线程 // - 全部基于同源调用构造函数 // - 所有脚本解析为相同的 URL // - 所有线程都有相同的名称 new SharedWorker('./sharedWorker.js'); new SharedWorker('sharedWorker.js'); new SharedWorker('https://www.example.com/sharedWorker.js');
如果指定不同的名字,则会产生不同的共享工作者线程
// 实例化两个共享工作者线程 // - 一个线程名称为'foo',一个线程名称为'bar' new SharedWorker('./sharedWorker.js', {name: 'foo'}); new SharedWorker('./sharedWorker.js', {name: 'foo'}); new SharedWorker('./sharedWorker.js', {name: 'bar'});
-
使用MessagePort进行通信,方便管理多个端口
SharedWorkerGlobalScope
在共享线程内部,全局作用域是 SharedWorkerGlobalScope 的实例,有以下属性和方法
属性 | 说明 |
---|---|
name | 给Worker起的名字 |
importScripts | 于向工作者线程中导入任意数量的脚本 |
close() | 内部自我关闭线程方法,与 worker.terminate()对应 |
onconnect | 监听共享线程连接,也可以通过使用 sharedWorker.addEventListener('connect', handler) |
二、用法
创建一个Worker语法如下:
const worker = new SharedWorker('./test.js')
// 通过worker.port发送消息
worker.port.postMessage("xxx");
下面看一个简单的点赞小例子:
sharedworker.html
<body>
<h3>共享线程 Shared Worker</h3>
<button id="likeBtn">点赞</button>
<p>一共收获了<span id="likedCount">0</span>个👍</p>
<script>
let likeBtn = document.querySelector("#likeBtn");
let likedCountEl = document.querySelector("#likedCount");
let worker = new SharedWorker("./shared-worker.js",{ name: 'test_shared_worker' });
worker.port.start();
likeBtn.addEventListener("click", function () {
worker.port.postMessage("2");
});
worker.port.onmessage = function (val) {
likedCountEl.innerHTML = val.data;
};
</script>
</body>
点击页面上的按钮,每次+2个点赞数量
worker.js内容如下:
let a = 0;
console.log('shared worker is working...');
self.onconnect = function (event) {
console.log(event);
const port_0 = event.ports[0];
port_0.onmessage = function (e) {
const incr = Number(e.data);
a = a+ incr;
port_0.postMessage(a);
}
}
每次点击按钮都会向worker通信一次,worker内部记住点赞数量,然后再返回给主程序,界面就能显示点赞了多少次。
console.log不见了?
F12打开控制台发现,并没有输出任何内容,那是因为SharedWorker必须通过
chrome://inspect
命令才能看到输出的内容,尝试在地址栏输入试试看
可以看出,确实存在了我们的共享工作者线程,点击inspect就能看到控制台内容
三、多页面通信
ShareWorker.js
var clients = [];
onconnect = function(e) {
var port = e.ports[0];
clients.push(port);
port.addEventListener('message', function(e) {
for (var i = 0; i < clients.length; i++) {
var eElement = clients[i];
eElement.postMessage(e.data)
}
});
port.start();
}
在需要推送的页面里面添加开启共享线程的代码,shareworker-message.js
myWorker = new SharedWorker("script/scenesetting/ShareWorker.js");
myWorker.port.onmessage=function(e) {
var result=e.data;//此处就是共享现成推送过来的数据可以是字符串、数组、json
/***********上面拿到数据后,就可以在下面做一些你想造做的事************/
};
引用第二步的shareworker-message.js文件
myWorker.port.postMessage(newData);
另外一个案例,请参考:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)