self.skipWaiting()在Service Worker中不起作用

时间:2019-02-11 10:39:01

标签: javascript service-worker service-worker-events

我有一名服务人员。这是安装事件:

self.addEventListener('install', function (event) {
    console.log('Installing Service Worker ...', event);

    return self.skipWaiting()
    .then(() => caches.open(CACHE_STATIC_NAME))
    .then(function (cache) {
        return cache.addAll([
            './file1.html',
            './file2.html'
        ])
    })
});

由于某些原因,当我编辑服务工作者代码并更新服务工作者文件URL中的查询参数时,它会安装但不会激活(根据Chrome DevTools)—即使我叫self.skipWaiting()

奇怪的是,如果我进入控制台,请转到服务工作者的范围并自己输入self.skipWaiting(),它将立即激活。

很多小时以来,我一直在努力弄清正在发生的事情,而我完全陷入了困境。这里有我想念的东西吗?

2 个答案:

答案 0 :(得分:0)

旧的SW可能仍在运行任务时不会停止-例如,如果它具有长时间运行的获取请求(例如服务器发送的事件/事件源或获取流;尽管我不认为websocket会导致此为SW我会忽略它们)。

我发现浏览器之间的行为是不同的。 Chrome似乎在等待现有任务运行时等待(因此skipWaiting将失败...),但是Safari似乎会终止该任务并激活新的软件。

测试这是否引起问题的一种好方法是在请求skipWaiting之后立即终止服务器(终止网络连接)。 (仅在开发工具中单击“脱机”似乎并不会杀死所有正在运行的连接,例如EventSources仍在运行。)

您可以让SW忽略某些路由(如下),或者可以尝试强制终止请求(也许使用AbortController)。

self.addEventListener('fetch', function(event) {
  const { method, url } = event.request;
  if(event.request.method !== "GET") return false;
  if(url === "https://example.com/poll") return false;

  event.respondWith(
    caches.match(match).then(function(response) {
      return response || fetch(event.request);
    })
  );
});

skipWaiting的过程在此规范中:

https://w3c.github.io/ServiceWorker/#try-activate-algorithm

但是我不清楚在激活新软件之前浏览器是应该等待任务还是终止任务(或将它们转移到新软件?)。并且如前所述,目前浏览器之间的工作方式似乎有所不同...

答案 1 :(得分:0)

我也遇到过同样的问题。

我通过@ej.daly 给出的技巧验证了我的问题,即我应该停止服务器,WAITING service-worker 将在几分钟后变为活动状态。

在那之后,我在我的代码中应用了一个黑客:如果 WAITING 服务工作者在接下来的 3 秒内没有被激活,则重新加载窗口。

顺便说一句,我正在开发一个库,以便在我们公司的各种(常用)场景中轻松安装 service-worker。看看https://github.com/DreamworldSolutions/workbox-installer