信息化网站建设有什么用,专业网站建设公司在线咨询,巩固网站访客量,华为云建站和阿里云建站区别前言
serviceWorker 的能力决定它要处理的事情#xff0c;网站页面的部分逻辑处理会转移到 serviceWorker 层进行处理#xff0c;这里就要页面层和 serviceWorker 层进行交互来实现消息通讯。
下面就说一下两个环境下的消息通讯。 窗口向 serviceWorker 通讯
这里列举出窗…前言
serviceWorker 的能力决定它要处理的事情网站页面的部分逻辑处理会转移到 serviceWorker 层进行处理这里就要页面层和 serviceWorker 层进行交互来实现消息通讯。
下面就说一下两个环境下的消息通讯。 窗口向 serviceWorker 通讯
这里列举出窗口层到 serviceWorker 层的通讯方法。
1. ServiceWorker.postMessage
页面层可以通过 ServiceWorker 接口的 postMessage 来实现页面到 serviceWorker 环境的通讯。
ServiceWorker 接口的获取:
ServiceWorker 接口获取有两种方式
navigator.serviceWorker.controller常用这种方式。navigator.serviceWorker.ready.then(swReg swReg[state])state 为 {installing, waiting, active} 。
当 postMessage 后serviceWorker 环境采用 onmessage 事件进行处理。
发送消息 发送消息实现
index.html
// 页面 window 环境if(navigator.serviceWorker.controller) { // 需要判断是否受控navigator.serviceWorker.controller.postMessage(消息); // postMessage 的第一个参数可以是由结构化克隆算法处理的任何值或JavaScript对象也包括循环引用。
}sw.js
// serviceWorker 环境self.addEventListener(message, e {console.log(message, e);// 从 e.data 里面取 postMessage 过来的数据
})接收消息 页面层 window 环境下接收消息需要在 ServiceWorkerContainer 接口上监听 onmessage
navigator.serviceWorker.onmessageserviceWorker 层做定向 Client 的获取有以下方式
// 1. 通过 e.source.id 来定向发送消息self.addEventListener(message, e {const client await self.clients.get(e.source.id);client.postMessage(发给页面层的消息);
})// 2. 直接 e.source 来定向发送消息self.addEventListener(message, e {e.source.postMessage(发给页面层的消息);
})2. ServiceWorkerRegistration.sync.register
第二种方式是使用 sync 的方式来实现页面层到 serviceWorker 层的通讯。 这种通讯的弊端是单向的且不可控。
但优势也很明显对于后台同步十分有用一旦注册 sync 在 online 的状态下会立即触发 serviceWorker 环境下的 onsync 事件serviceWorker 可根据具体逻辑处理直到 e.waitUntil 返回 Promise.resolve() 才会完成 sync并把 sync 的 tag 清除否则会一直按照某个周期执行知道 e.lastChance true。
// 页面层环境navigator.serviceWorker.ready.then(swReg {swReg.sync.register(同步tag)
})// serviceWorker 层环境self.addEventListener(sync, e {if(e.tag 同步tag) {e.waitUntil(new Promise((res, rej) {// 逻辑处理 ...return res();}))}
})3. MessageChannel
MessageChannel 是一个点对点的消息通道可以很方便的实现消息的双向通讯。 构造函数
构造函数很简单不需要任何参数
var channel new MessageChannel();属性
MessageChannel.port1MessageChannel.port2
属性中的两个 port 为 MessagePort 接口实现具备以下方法
postMessagestartclose
具备事件监听MessagePort.onmessage。
这里发消息时主要以环境下的 postMessage 配合使用。
// 页面层环境if(navigator.serviceWorker.controller) {var c new MessageChannel();c.port1.onmessage e {// 收到传给 port1 的消息}// 向 port2 发送消息navigator.serviceWorker.controller.postMessage(消息, [c.port2])
}// serviceWorker 层self.addEventListener(message, e {// 从 e.ports 里取 MessagePorte.ports[0] e.ports[0].postMessage(向port1发送消息)
})注意MessageChannel 创建的通道会受 serviceWorker 的 stopWorker 影响导致 MessageChannel 通道 close也就是表现为通道只能用一次。所以使用 MessageChannel 通讯时每次都要创建新的通道。 serviceWorker 向窗口通讯
上面说的是窗口页面层向 serviceWorker 环境的通讯同样 serviceWorker 环境层也需要向页面层通讯。
在 serviceWorker 环境下主要有两种向页面层通讯的方式。
1. BroadcastChannel
第一种是 BroadcastChannel也就是广播信道通讯。
构造函数
构造函数很简单channel 参数为一个字符串。
var channel new BroadcastChannel(channel);属性
BroadcastChannel.name构造时的信道名。
事件
onmessageonmessageerror
方法
postMessage()close() // 页面层var bc1 new BroadcastChannel(c1);bc1.onmessage e {// 页面层收到广播逻辑处理
}// serviceWorker 层var bc1 new BroadcastChannel(c1);bc1.postMessage(发送广播消息);2. client.postMessage
第二种就是获取相应的 client 进行 postMessage。
如果从 onmessage 中是可以获取到相应的 sorce client 的从而进行双向通讯。但在自发情况下只能对所有 client 进行广播通讯。 // serviceWorker 环境clients.matchAll({type: window
})
.then(windows {for (const win of windows) {win.postMessage(发送消息到页面);}
});博客名称王乐平博客 CSDN博客地址http://blog.csdn.net/lecepin 本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。