最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - To check if ServiceWorker is in waiting state - Stack Overflow

programmeradmin1浏览0评论

I am trying to understand the Service Worker API, and I know the bits and parts about registering a Service Worker.

As stated in the API doc, if a service worker update is found, the service worker is registered and added to the queue. This SW takes over a page if and only if, the page is closed and opened again.That is, A window is closed and reopened again.

Now, this has a few downfalls:

  1. The user might be seeing a previous version that might have a very serious grammatical mistake, or whatever.

  2. The user needs to be somehow notified that the content has changed and that a referesh would do it.

I know how to tell the SW.js to skipWaiting() and take over. I also know how to send a message to the SW.js telling it that the user wants a automatic refresh.

However, what I do not know is how to know whether a new SW is actually in a waiting state.

I have used this:

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

    });

However, it usually returns the waiting state as null.(Possibly because the SW is still installing when the request is fired.)

How can I know on the client page that a waiting service worker is available?

I am trying to understand the Service Worker API, and I know the bits and parts about registering a Service Worker.

As stated in the API doc, if a service worker update is found, the service worker is registered and added to the queue. This SW takes over a page if and only if, the page is closed and opened again.That is, A window is closed and reopened again.

Now, this has a few downfalls:

  1. The user might be seeing a previous version that might have a very serious grammatical mistake, or whatever.

  2. The user needs to be somehow notified that the content has changed and that a referesh would do it.

I know how to tell the SW.js to skipWaiting() and take over. I also know how to send a message to the SW.js telling it that the user wants a automatic refresh.

However, what I do not know is how to know whether a new SW is actually in a waiting state.

I have used this:

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

    });

However, it usually returns the waiting state as null.(Possibly because the SW is still installing when the request is fired.)

How can I know on the client page that a waiting service worker is available?

Share Improve this question edited Apr 2, 2021 at 9:02 Serge Stroobandt 31.5k9 gold badges120 silver badges109 bronze badges asked Jun 1, 2016 at 15:53 codecode 2,1631 gold badge25 silver badges50 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 22

Here's some code that will detect and allow you to handle various states whenever there's a new or updated service worker registration.

Please note that the log message assumes that skipWaiting() is not being called during the service worker's installation; if it is being called, then instead of having to close all tabs to get the new service worker to activate, it will just activate automatically.

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!');
            }
          }
        });
      });
    }
  });
}
发布评论

评论列表(0)

  1. 暂无评论