我希望能够完全控制我的Service Worker
版本,我创建了信号和函数,允许我使用update
或skipWaiting
——一个运行良好的现有Service Worker
!
self.addEventListener('install',event=>
event.waitUntil(caches.open(version).then(cache=>
cache.addAll([
...
]).then(_=>
condition?
self.skipWaiting():
false
)
))
)
self.addEventListener('activate',event=>
event.waitUntil(clients.claim())
)
当我调用skipWaiting
时,客户端页面由新的Service Worker
声明,正如它应该声明的那样,
但我无法让它立即从新安装的Service Worker
的新缓存中重新加载。
如何skipWaiting
并强制所有客户端页面从新安装的Service Worker
的缓存中自行重新加载?
尝试以下代码片段:
// If service workers are supported...
if ('serviceWorker' in navigator) {
// Check to see if the page is currently controlled.
let isControlled = Boolean(navigator.serviceWorker.controller);
// Listen for a change to the current controller...
navigator.serviceWorker.addEventListener('controllerchange', () => {
if (isControlled) {
// ...and if the page was previosly controlled, reload the page.
window.location.reload();
} else {
// ...otherwise, set the flag for future updates, but don't reload.
isControlled = true;
}
});
}
我建议将此逻辑建立在controllerchange
事件的基础上,而不是其他一些方法,如监听安装/等待服务工作者的statechange
,因为服务工作者激活和控制现有客户端之间的时间间隔很小。在每个页面上等待controller
的更改将保证在更新的服务工作者的控制下进行重新加载。
将此代码与调用skipWaiting()
的服务工作者结合使用,应该可以为您提供所需的行为。