Web Worker: Shared Worker的使用

Web Worker: Shared Worker的使用


参考资料:

一、概述

​ 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个点赞数量
image

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命令才能看到输出的内容,尝试在地址栏输入试试看

image

可以看出,确实存在了我们的共享工作者线程,点击inspect就能看到控制台内容

三、多页面通信

来源:https://zhuanlan.zhihu.com/p/38380765

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);

另外一个案例,请参考:

https://blog.51cto.com/u_11711012/4919513

posted @   SuanYunyan  阅读(851)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示