显示服务工作者状态的消息

时间:2016-05-14 00:43:08

标签: javascript service-worker

我上周一直在为Service Worker工作,目前有一个很棒的安装方法可以离线缓存文件并推送通知。

还有最后一件事,我希望能够在UI中显示服务工作者的某些状态的消息,目前我有以下代码用于激活状态:

if ('serviceWorker' in navigator) {
navigator.serviceWorker.addEventListener('controllerchange',function(event) {
  navigator.serviceWorker.controller.addEventListener('statechange', function() {
if (this.state === 'activated') {
  document.getElementById('offlineNotification').classList.remove('hidden');
}
});
});
}

现在我想为安装状态创建一条消息,允许我显示类似“脱机服务正在更新”的消息,如果有人正在处理此问题,并知道如何操作,请让我知道。

我已经尝试了相同的代码但是使用“if(this.state ==='安装')”

“if(this.state ==='install'”

似乎都没有效果。

3 个答案:

答案 0 :(得分:4)

服务工作者的生命周期与您的网页完全分开。 要为您的站点安装服务工作者,您需要注册它。

self.addEventListener('install', function(event) {
    // Perform install steps
});

当我们安装时,激活步骤将随之而来,这是处理旧缓存管理的绝佳机会。

self.addEventListener('activate', function(event) {
    // Perform activate steps, Typically cache management.
});

在激活步骤之后,服务工作者将控制属于其范围的所有页面,尽管第一次注册服务工作者的页面在再次加载之前将不会被控制。

一旦服务人员处于控制状态,它将处于以下两种状态之一:either the service worker will be terminated以节省内存,或it will handle fetch and message events在您的页面发出网络请求或消息时发生。 你也可以试试像,

if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/sw.js').then(function(reg) {
        // updatefound is fired if service-worker.js changes.
        reg.onupdatefound = function() {
          var installingWorker = reg.installing;

          installingWorker.onstatechange = function() {
            switch (installingWorker.state) {
              case 'installed':
                if (navigator.serviceWorker.controller) {
                  // At this point, the old content will have been purged and the fresh content will have been added to the cache.
                  // It's the perfect time to display a "New content is available; please refresh."
                  console.log('New or updated content is available.');
                } else {
                  // At this point, everything has been precached.
                  // It's the perfect time to display a "Content is cached for offline use." message.
                  console.log('Content is now available offline!');
                }
                break;

              case 'redundant':
                console.error('The installing service worker became redundant.');
                break;
            }
          };
        };
      }).catch(function(e) {
        console.error('Error during service worker registration:', e);
      });
    }

答案 1 :(得分:0)

查看ServiceWorker Cookbook上的live flowchart demo和Telegram使用的code snippet,以便在有更新时通知用户。

答案 2 :(得分:0)

这是因为代码中的this始终引用页面的activated服务工作者。

navigator.serviceWorker.controller只会引用您页面的一名服务工作者,而后者是当前控制中的服务工作者。如果在服务页面控制着您的页面的同时安装了另一个服务页面,那么它将在您的ServiceWorkerRegistration(即installing或{{ 1}})。

您想要的是在waiting事件处理程序(而不是ServiceWorkerRegistration)内引用此navigator.serviceWorker.controller上的各种状态(而不是您的updatefound):< / p>

controllerchange

我相信if ('serviceWorker' in navigator) { const registration = await navigator.serviceWorker.register('serviceWorker.js'); // Or, if not using async/await... //navigator.serviceWorker.register('serviceWorker.js').then(function(registration) { registration.addEventListener('updatefound', function(e) { const newSw = e.target.installing || e.target.waiting; newSw.addEventListener('statechange', function() { if (this.state === 'activated') { document.getElementById('offlineNotification').classList.remove('hidden'); /* else if handlers for any of the following (or, better yet, a switch statement): 'installing' 'installed' 'activating' 'activated' (handled above) 'redundant' */ } }); }); } 仅在控制器合法更改时才调用,只有当您通过controllerchangeskipWaiting()在服务工作者中明确声明对客户端的控制权时才会发生或者,如果您在开发工具中摆弄,并强迫新的服务人员进行控制。这样,您将永远不会在该控制器上看到clients.claim(),因为它已经超过了installinginstallinginstalled才能触发activating事件。

一些有用的链接:

MDN - ServiceWorkerContainer.controller

MDN - ServiceWorkerRegistration

MDN - ServiceWorker.onstatechange

A detailed demonstration of service worker lifecycle and state change detection