为什么我的服务工作者总是等待激活?

24

我有一个非常基本的问题。

我正在努力理解Service Worker生命周期,或者更好的说,是在实际情况下如何初始化和改变状态。

我现在有2个问题:

1 - 在chrome://inspect/#service-workers中,总是有2或3条线,显示所有运行相同PID的服务工作者。为什么?为什么不只有一个?

2- 当我刷新后检查我的服务工作者时,我得到了这个:

  • #566已激活并正在运行 [stop]
  • #570等待激活 [skipWaiting]

那是什么意思?566和570是什么?我想它们是sw的实例,但为什么会有两个?为什么570还在等待?我应该做些什么来确保它将被注册-安装-激活?

3- 一般性问题

  • 什么结束了正常生命周期中的install事件?
  • 什么触发了正常生命周期中的activate事件?

index.html

<script>
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
      navigator.serviceWorker.register('./sw.js')
      .then(function(registration) {
        // successful
        console.log('Success: ', registration);
      }).catch(function(err) {
        // registration failed
        console.log('Error: ', err);
      });
    });
  }
  </script>

sw.js

var cache_name = 'v1';

var cache_files = [
  './',
  './index.html',
  './style.css'
]

self.addEventListener('install', function(e){
  console.log('SW install:', e);
  e.waitUntil(
    caches.open(cache_name)
    .then(function(cache){
      console.log('cache', cache);
      return cache.addAll(cache_files);
    })
    .then(function(cache){
      console.log('Cache completed');
    })
  )
});

self.addEventListener('activate', function(event) {
  console.log('SW activate:', event);
});

self.addEventListener('fetch', function(e){
  console.log('SW fetch:', e.request.url)

  e.respondWith(
    caches.match(e.request)
    .then(function(cache_response){
      if(cache_response) return cache_response;

      return fetch(e.request);
    })
    .catch(function(err){
      console.log('Cache error', err)
    })
  );
});

谢谢!


你能展示一些代码吗?也许你注册了两次?其中一个服务工作者可能是旧版本,尚未注销。 - Henrik Andersson
只允许一次注册。我会更新代码。 - Victor Ferreira
1
我遇到了同样的问题。它总是停留在待处理状态。@HenrikAndersson如何确保旧版本未注册? - user3260861
1个回答

43
Chrome Devtools显示的id是内部id,仅供参考。因此,它们通过一个id来命名所有的Service Worker。这就是全部内容。
在“同一时间”内拥有两个Service Worker的原因是您先有一个,然后重新加载页面、导航离开并返回,或者类似的操作,就会得到另一个Service Worker。但是,在此时,“刚得到另一个”的Service Worker尚未被激活,之前的Service Worker仍在控制页面。只有当您从其他位置返回站点时,新的Service Worker才会接管先前的Service Worker,刷新页面是不够的。基本上,这意味着关闭页面的所有选项卡和窗口,然后再次加载它,然后新的Service Worker接管。
新Service Worker尚未接管的时间称为等待状态,它发生在安装和激活之间。可以通过在Service Worker的安装处理程序中调用self.skipWaiting()来跳过此步骤。
这个流程背后的基本思想是,页面不应该由在页面加载时没有控制页面的Service Worker控制 - 出于这个原因,对于注册Service Worker的站点的第一次访问,将不会由该Service Worker控制,只有第二次访问以及之后才会激活Service Worker等等。
你应该真的阅读这篇精彩的文章:Service Worker 的生命周期

这是有关 skipWaiting 调用的一些文档 https://developers.google.com/web/ilt/pwa/lab-scripting-the-service-worker#33_skipping_the_waiting_phase - ap.dev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接