检查ServiceWorker是否处于等待状态

5
我正在尝试理解Service Worker API,并且我知道有关注册Service Worker的各个部分。
根据API文档所述,如果找到服务工作者更新,则会将服务工作者注册并添加到队列中。仅当页面关闭并再次打开时,此SW才接管页面。也就是说,窗口被关闭并重新打开。
现在,这有一些缺点:
1. 用户可能会看到先前版本,其中可能存在非常严重的语法错误或其他问题。 2. 需要以某种方式通知用户内容已更改,刷新即可。
我知道如何告诉SW.js跳过等待(skipWaiting())并接管它。我也知道如何向SW.js发送消息,告诉它用户想要自动刷新。
但是,我不知道如何知道新的SW是否实际处于等待状态。
我已经使用了这个:
navigator.serviceWorker.ready.then((a) => {
        console.log("Response, ", a);
        if (a.waiting !== null && a.waiting.state === "installed") {
            console.log("okay");
        }

    });

然而,通常它会返回等待状态作为null。(可能是因为当请求被触发时软件仍在安装中。)

我如何在客户端页面上知道可用的等待服务工作者?

1个回答

20
以下是关于检测和处理新的或更新的服务工作者注册时各种状态的代码。
请注意,日志消息假定在服务工作者安装期间未调用skipWaiting(); 如果正在调用,则无需关闭所有选项卡即可自动激活新的服务工作者。
if ('serviceWorker' in navigator) {
  window.addEventListener('load', async function() {
    const registration = await navigator.serviceWorker.register('/service-worker.js');
    if (registration.waiting && registration.active) {
      // The page has been loaded when there's already a waiting and active SW.
      // This would happen if skipWaiting() isn't being called, and there are
      // still old tabs open.
      console.log('Please close all tabs to get updates.');
    } else {
      // updatefound is also fired for the very first install. ¯\_(ツ)_/¯
      registration.addEventListener('updatefound', () => {
        registration.installing.addEventListener('statechange', () => {
          if (event.target.state === 'installed') {
            if (registration.active) {
              // If there's already an active SW, and skipWaiting() is not
              // called in the SW, then the user needs to close all their
              // tabs before they'll get updates.
              console.log('Please close all tabs to get updates.');
            } else {
              // Otherwise, this newly installed SW will soon become the
              // active SW. Rather than explicitly wait for that to happen,
              // just show the initial "content is cached" message.
              console.log('Content is cached for the first time!');
            }
          }
        });
      });
    }
  });
}

这太棒了。我本应该自己查看文档的,不过无论如何,谢谢。 - code
Jeff,看起来我在你的代码中发现了一个错误:'waiting'不是服务工作者的有效状态('installing'、'installed'、'activating'、'activated'和'redundant'是服务工作者的有效状态)。'waiting'(以及'installing'和'active')是注册的属性,而不是服务工作者的属性。 - Alexey Rodionov
谢谢,我最近一直在使用https://gist.github.com/jeffposnick/f3e173a89adfd0ce1e664442ae7f8a27 ,并将更新旧答案。 - Jeff Posnick
@JeffPosnick请问updatedSW是在哪里定义的? - Zephyr was a Friend of Mine
抱歉,那是早期版本的遗留问题。我已经将其改为使用 event.target - Jeff Posnick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接