Eth*_*han 8 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'
])
})
});
Run Code Online (Sandbox Code Playgroud)
出于某种原因,当我编辑服务工作者代码并更新服务工作者文件 URL 中的查询参数时,它会安装但不会激活(根据 Chrome DevTools)——即使我已经调用了self.skipWaiting().
奇怪的是,如果我进入控制台,进入 service worker 的范围并输入self.skipWaiting()自己,它会立即激活。
几个小时以来,我一直试图弄清楚发生了什么,但我完全被难住了。有什么我在这里想念的吗?
小智 8
旧的 SW 在它仍在运行任务时可能不会停止 - 例如,如果它有一个长时间运行的获取请求(例如服务器发送的事件/事件源,或获取流;尽管我认为 websockets 不会导致这种情况,因为 SW 会忽略它们我认为)。
但是,我发现浏览器之间的行为有所不同。Chrome 似乎在现有任务运行时等待(因此 skipWaiting 将失败...),但 Safari 似乎终止了任务并激活了新的 SW。
测试这是否导致您的问题的一个好方法是在您请求 skipWaiting(以终止网络连接)之后立即终止您的服务器。(只是在开发工具中点击“离线”似乎并没有杀死所有正在运行的连接,例如 EventSources 保持运行。)
您可以让软件忽略某些路由(如下),或者您可以尝试强制请求终止(可能使用 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);
})
);
});
Run Code Online (Sandbox Code Playgroud)
skipWaiting 的过程在这个规范中:
https://w3c.github.io/ServiceWorker/#try-activate-algorithm
但是我不太清楚浏览器是否应该在激活新软件之前等待任务或终止它们(或将它们转移到新软件?);如前所述,目前浏览器之间的工作方式似乎有所不同......