• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    html5中sharedWorker实现多页面通信的示例代码

    发布者: 雪落无声 | 发布时间: 2025-6-16 12:22| 查看数: 145| 评论数: 0|帖子模式

    是这样的,今天玩github,先是在没有登录浏览了一些页面,然后在某一页面进行了登录。这时再切换的其他页面时就看到了下面的提示:

    那么这是怎么做到的呢?我们可以想到,一种办法是 localStorage,在某一个页面登录时,修改localStorage 状态,其他页面在显示的时候,读取最新的状态,然后显示提示:
    1. // 登录的页面
    2. localStorage.setItem('login', true);

    3. // 其他页面
    4. document.addEventListener("visibilitychange", function() {
    5.         if (localStorage.setItem('login') === 'true') {
    6.                 alert('你已登录,请刷新页面');
    7.         }
    8. }
    复制代码
    然而,github并没有这么做,localStorage里也找不到相关的字段,一番查找之后,发现他们是用 sharedWorker 实现的。那我们就来了解下sharedworker

    什么是sharedWorker

    sharedWorker 顾名思义,是 worker 的一种,可以由所有同源的页面共享。同Worker的api一样,传入js的url,就可以注册一个 sharedWorker 实例:
    1. let myWorker = new SharedWorker('worker.js');
    复制代码
    但是与普通 Worker 不同的是:
    1 同一个js url 只会创建一个 sharedWorker,其他页面再使用同样的url创建sharedWorker,会复用已创建的 worker,这个worker由那几个页面共享。
    2 sharedWorker通过port来发送和接收消息
    接下来,我们看一下具体是 worker 和页面之间是如何发送和接收消息的。
    messagePort

    假设我们有两个js,一个是跑在页面里的 page.js,另一个是跑在 worker里的 worker.js。那么我们要在 page.js 里注册一个 sharedWorker,代码如下:
    1. // page.js
    2. let myWorker = new SharedWorker('worker.js');
    3. // page通过worker port发送消息
    4. myWorker.port.postMessage('哼哼');
    5. // page通过worker port接收消息
    6. myWorker.port.onmessage = (e) => console.log(e.data);

    7. // worker.js
    8. onconnect= function(e) {
    9.         const port = e.ports[0];
    10.         port.postMessage('哈嘿');
    11.         port.onmessage = (e) => {
    12.                 console.log(e.data);
    13.         }
    14. }
    复制代码
    调试sharedWorker

    在上面的例子中,我们在worker中使用了console.log来打印来自页面的message,那么到哪里可以看到打印的log呢?我们可以在浏览器地址栏里面输入 `chrome://inspect,然后在侧边栏选中shared workers了,就可以看到浏览器,目前在运行的所有worker。点击inspect会打开一个开发者工具,然后就可以看到输出的log了。

    这里我们看到我们的worker名字是untitled,那是因为sharedworker 构造函数还支持传入第二个参数作为名字:
    1. let myWorker = new SharedWorker('worker.js', 'awesome worker');
    复制代码
    多页面发布消息

    回到文章一开始的例子,我们前面实现了页面和worker之间的通信,那么该如何让worker向多个页面发送消息呢?一个思路就是我们把port缓存起来,作为一个port pool,这样当我们需要向所有页面广播消息的时候,就可以遍历port,然后发送消息:
    1. // worker js
    2. const portPool = [];
    3. onconnect= function(e) {
    4.         const port = e.ports[0];
    5.         // 在connect时将 port添加到 portPool中
    6.         portPool.push(port);
    7.         port.postMessage('哈嘿');
    8.         port.onmessage = (e) => {
    9.                 console.log(e.data);
    10.         }
    11. }

    12. function boardcast(message) {
    13.         portPool.forEach(port => {
    14.                 port.portMessage(port);
    15.         })
    16. }
    复制代码
    这样我们就基本实现了向多个页面广播消息的功能。
    清除无效的port

    上面的实现中有一个问题,就是在页面关闭后,workerPool中的port并不会自动清除,造成内存的白白浪费。我们可以在页面关闭前通知shared worker页面将要关闭,然后让worker将无效的 messagePort 从 portPool 中移除。
    1. // 页面
    2. window.onbeforeunload = () => {
    3.   myWorker.port.postMessage('TO BE CLOSED');
    4. };

    5. // worker.js
    6. const portPool = [];
    7. onconnect = function(e) {
    8.   var port = e.ports[0];
    9.   portPool.push(port);
    10.   port.onmessage = function(e) {
    11.     console.log(e);
    12.     if (e.data === 'TO BE CLOSED') {
    13.       const index = ports.findIndex(p => p === port);
    14.       portPool.splice(index, 1);
    15.     }
    16.     var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
    17.     port.postMessage(workerResult);
    18.   }
    19. }

    20. function boardcast(message) {
    21.         portPool.forEach(port => {
    22.                 port.portMessage(port);
    23.         })
    24. }
    复制代码
    这样,我们就实现了一个简单的多页面广播的sharedWorker。我们可以用它来广播一下时间:
    1. setInterval(() => boardcast(Date.now()), 1000);
    复制代码
    参考

    https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/SharedWorker
    https://github.com/mdn/simple-shared-worker
    到此这篇关于html5中sharedWorker实现多页面通信的示例代码的文章就介绍到这了,更多相关html5 sharedWorker多页面通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!

    来源:https://www.jb51.net/html5/774356.html
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表