• 售前

  • 售后

热门帖子
入门百科

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

[复制链接]
123456809 显示全部楼层 发表于 2021-8-14 14:47:44 |阅读模式 打印 上一主题 下一主题
是如许的,今天玩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多页面通讯内容请搜索草根技能分享以前的文章或继续欣赏下面的相关文章,盼望大家以后多多支持草根技能分享!

本帖子中包含更多资源

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

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作