ServiceWorker 的冗余状态应该怎么办?

What should I do with the redundant state of a ServiceWorker?

我需要一个 serviceworker 的配套脚本,我现在正在试用。

脚本的工作原理如下:

((n, d) => {

  if (!(n.serviceWorker && (typeof Cache !== 'undefined' && Cache.prototype.addAll))) return; 

  n.serviceWorker.register('/serviceworker.js', { scope: './book/' })
    .then(function(reg) {

        if (!n.serviceWorker.controller) return;

        reg.onupdatefound = () => {

          let installingWorker = reg.installing;

          installingWorker.onstatechange = () => {
            switch (installingWorker.state) {
              case 'installed':
                if (navigator.serviceWorker.controller) {
                  updateReady(reg.waiting);

                } else {
                  // This is the initial serviceworker…
                  console.log('May be skipwaiting here?');
                }
                break;

              case 'waiting':
                updateReady(reg.waiting);
                break;

              case 'redundant':
                // Something went wrong?
                console.log('[Companion] new SW could not install…')
                break;
            }
          };
        };
    }).catch((err) => {
      //console.log('[Companion] Something went wrong…', err);
    });

    function updateReady(worker) {
        d.getElementById('swNotifier').classList.remove('hidden');

        λ('refreshServiceWorkerButton').on('click', function(event) {
          event.preventDefault();
          worker.postMessage({ 'refreshServiceWorker': true } );
        });

        λ('cancelRefresh').on('click', function(event) {
          event.preventDefault();
          d.getElementById('swNotifier').classList.add('hidden');
        });

    }

    function λ(selector) {

      let self = {};

      self.selector = selector;

      self.element = d.getElementById(self.selector);

      self.on = function(type, callback) {
        self.element['on' + type] = callback;
      };

      return self;
    }

    let refreshing;

    n.serviceWorker.addEventListener('controllerchange', function() {
      if (refreshing) return;
      window.location.reload();
      refreshing = true;
    });    


})(navigator, document);

我现在对服务人员的庞大 api 有点不知所措,无法 "see" 如果 reg.installing 返回一个 redundant状态?

抱歉,如果这看起来像一个愚蠢的问题,但我是 serviceworkers 的新手。

根据这里的定义https://www.w3.org/TR/service-workers/#service-worker-state-attribute我猜只是打印一个日志,以防它在调试时出现,否则什么都不做。

很难弄清楚你的意图,所以我会尝试笼统地回答这个问题。

如果 Service Worker 安装失败或被更新的 Service Worker 取代,该 Service Worker 将变得多余。

发生这种情况时您该怎么办取决于您。在这些情况下你想做什么?

写catch函数看错误。可能是 SSL 问题。

/* In main.js */
if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('./sw.js')
    .then(function(registration) {
        console.log("Service Worker Registered", registration);
    })
    .catch(function(err) {
        console.log("Service Worker Failed to Register", err);
    })
}

您应该删除您创建的任何 UI 提示,这些提示要求用户执行 某事 以激活最新的服务工作者。再耐心一点。

你有 3 个 service worker,正如你在 registration:

上看到的
  1. active:就是运行
  2. waiting:已下载,准备成为active
  3. installing:刚找到的,正在下载,下载后变成waiting

当服务人员到达#2 时,您可能会向用户显示一条提示,提示您只需点击一下即可获得新版本的应用程序。假设他们不采取行动。

然后你发布一个新版本。您的应用检测到新版本,并开始下载它。此时,您有 3 个服务人员。 #2 处的那个变为 redundant。 #3 的那个还没有准备好。您应该删除该提示。

#3 下载完成后,它将取代#2,您可以再次显示该提示。