这篇文章主要讲解了“html5中怎么使用sharedWorker实现多页面通信”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“html5中怎么使用sharedWorker实现多页面通信”吧!

我们可以想到,一种办法是 localStorage,在某一个页面登录时,修改localStorage 状态,其他页面在显示的时候,读取最新的状态,然后显示提示:

//登录的页面localStorage.setItem('login',true);//其他页面document.addEventListener("visibilitychange",function(){if(localStorage.setItem('login')==='true'){alert('你已登录,请刷新页面');}}

然而,github并没有这么做,localStorage里也找不到相关的字段,一番查找之后,发现他们是用 sharedWorker 实现的。那我们就来了解下sharedworker

什么是sharedWorker

sharedWorker 顾名思义,是 worker 的一种,可以由所有同源的页面共享。同Worker的api一样,传入js的url,就可以注册一个 sharedWorker 实例:

letmyWorker=newSharedWorker('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,代码如下:

//page.jsletmyWorker=newSharedWorker('worker.js');//page通过workerport发送消息myWorker.port.postMessage('哼哼');//page通过workerport接收消息myWorker.port.onmessage=(e)=>console.log(e.data);//worker.jsonconnect=function(e){constport=e.ports[0];port.postMessage('哈嘿');port.onmessage=(e)=>{console.log(e.data);}}调试sharedWorker

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

这里我们看到我们的worker名字是untitled,那是因为sharedworker 构造函数还支持传入第二个参数作为名字:

letmyWorker=newSharedWorker('worker.js','awesomeworker');多页面发布消息

回到文章一开始的例子,我们前面实现了页面和worker之间的通信,那么该如何让worker向多个页面发送消息呢?一个思路就是我们把port缓存起来,作为一个port pool,这样当我们需要向所有页面广播消息的时候,就可以遍历port,然后发送消息:

//workerjsconstportPool=[];onconnect=function(e){constport=e.ports[0];//在connect时将port添加到portPool中portPool.push(port);port.postMessage('哈嘿');port.onmessage=(e)=>{console.log(e.data);}}functionboardcast(message){portPool.forEach(port=>{port.portMessage(port);})}

这样我们就基本实现了向多个页面广播消息的功能。

清除无效的port

上面的实现中有一个问题,就是在页面关闭后,workerPool中的port并不会自动清除,造成内存的白白浪费。我们可以在页面关闭前通知shared worker页面将要关闭,然后让worker将无效的 messagePort 从 portPool 中移除。

//页面window.onbeforeunload=()=>{myWorker.port.postMessage('TOBECLOSED');};//worker.jsconstportPool=[];onconnect=function(e){varport=e.ports[0];portPool.push(port);port.onmessage=function(e){console.log(e);if(e.data==='TOBECLOSED'){constindex=ports.findIndex(p=>p===port);portPool.splice(index,1);}varworkerResult='Result:'+(e.data[0]*e.data[1]);port.postMessage(workerResult);}}functionboardcast(message){portPool.forEach(port=>{port.portMessage(port);})}

这样,我们就实现了一个简单的多页面广播的sharedWorker。我们可以用它来广播一下时间:

setInterval(()=>boardcast(Date.now()),1000);

感谢各位的阅读,以上就是“html5中怎么使用sharedWorker实现多页面通信”的内容了,经过本文的学习后,相信大家对html5中怎么使用sharedWorker实现多页面通信这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!