检查ServiceWorker是否处于等待状态

时间:2016-06-01 15:53:42

标签: javascript service-worker

我正在尝试了解Service Worker API,并且我知道有关注册服务工作者的各个部分。

如API文档中所述,如果找到服务工作者更新,则会注册服务工作者并将其添加到队列中。当且仅当页面关闭并再次打开时,此SW才会接管页面。也就是说,窗口关闭并重新打开。

现在,这有一些垮台,

1.用户可能会看到可能有严重语法错误的先前版本。或者无论如何。

  1. 用户需要以某种方式通知内容已发生变化并且裁判会这样做。
  2. 我知道如何告诉SW.js跳过Waiting()并接管。以及如何向SW.js发送消息,告诉用户想要自动刷新。

    然而,我不知道的是如何知道新SW是否实际处于等待状态。

    我用过这个:

    navigator.serviceWorker.ready.then((a) => {
            console.log("Response, ", a);
            if (a.waiting !== null && a.waiting.state === "installed") {
                console.log("okay");
            }
    
        });
    

    但它通常会将等待状态返回为null。(可能是因为SW在请求被触发时仍在安装。)

    我怎么知道客户页面上有等待的SW?

1 个答案:

答案 0 :(得分:5)

这里有一些代码可以检测并允许您在新的或更新的服务工作者注册时处理各种状态。

请注意,日志消息假定在服务工作者的安装过程中未调用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!');
            }
          }
        });
      });
    }
  });
}