【发布时间】:2021-05-07 20:17:32
【问题描述】:
我在我的 Angular 应用程序中使用 Workbox,我每 15 分钟检查一次更新,以便通知用户是否已部署新版本。
找到更新后,新的 Service Worker 已安装但未激活,因为此时我可以提示用户重新加载页面:
点击 OK 后,我可以通知我的 SW 跳过等待,因为他有这个 EventListener:
addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
skipWaiting();
}
});
这很好用,但有时(我还没有弄清楚为什么)新的软件会立即安装并激活而无需等待(即使没有发送任何消息)。 p>
这怎么可能?
我实现了 2 种方法来检查更新并做出相应的反应,这两种方法都会导致相同的问题。
第一种方式,来自官方Docs:
public async registerServiceWorker() {
this.workbox = new Workbox('/sw.js', {});
try {
this.workbox.addEventListener('waiting', () => promptTheUser());
this.swRegistration = await this.workbox.register();
} catch (e) {
console.log('[SW] error registering service worker', e);
}
}
public async checkForUpdate() {
return await this.swRegistration.update();
}
public activateNow() { // Called in the user prompt
this.workbox.addEventListener('controlling', (event) => {
window.location.reload();
});
if (this.swRegistration && this.swRegistration.waiting) {
messageSW(this.swRegistration.waiting, { type: 'SKIP_WAITING' });
}
}
第二种方式,使用ServiceWorkerRegistration.onupdatefound和ServiceWorkerContainer.oncontrollerchange的方式:
public async registerServiceWorker() {
this.workbox = new Workbox('/sw.js', {});
this.swRegistration = await this.workbox.register();
this.swRegistration.installing.addEventListener('statechange', () => {
if (this.swRegistration.waiting) {
promptTheUser();
}
});
}
public async checkForUpdate() {
return await this.swRegistration.update();
}
public activateNow() {
navigator.serviceWorker.addEventListener('controllerchange', () => {
window.location.reload();
});
if (this.swRegistration && this.swRegistration.waiting) {
messageSW(this.swRegistration.waiting, { type: 'SKIP_WAITING' });
}
}
方法 registerServiceWorker() 在应用程序启动时被调用。 两种方式都应该产生相同的结果,但如果没有达到“控制”状态,它们就不起作用。相反,新的软件只是安装一个激活的。
因此,页面永远不会重新加载,并且我的用户提示保持打开状态...
有什么想法吗?
【问题讨论】:
-
您所描述的内容听起来更像是浏览器错误,而不是 Workbox 或您的软件的问题。我的理解是,每当安装了新的 SW 并且已经有一个活动的 SW 控制了至少一个客户端时,该新的 SW 将一直等待直到调用
skipWaiting(),或者直到所有活动的 SW 的客户端都关闭。如果您可以重现不同的行为,我建议您使用 crbug.com/new 提交 Chrome 错误。