4

我正在尝试了解 Service Worker API,并且我知道有关注册 Service Worker 的点点滴滴。

如 API 文档中所述,如果发现 Service Worker 更新,则注册 Service Worker 并将其添加到队列中。当且仅当页面被关闭并再次打开时,此 SW 才会接管页面。即,窗口被关闭并再次重新打开。

现在,这有一些缺点:

  1. 用户可能会看到以前的版本可能有非常严重的语法错误,或者其他什么。

  2. 需要以某种方式通知用户内容已更改并且引用会执行此操作。

我知道如何告诉SW.jsskipWaiting()接管。我也知道如何发送消息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 仍在安装。)

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

4

1 回答 1

16

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

请注意,日志消息假定skipWaiting()在 service worker 安装期间没有被调用;如果它被调用,那么不必关闭所有选项卡来激活新的服务工作者,它将自动激活。

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!');
            }
          }
        });
      });
    }
  });
}
于 2016-06-02T03:38:57.100 回答