Service Worker 的中止控制器

Posted

技术标签:

【中文标题】Service Worker 的中止控制器【英文标题】:Abort Controller for Service Worker 【发布时间】:2020-10-04 18:21:29 【问题描述】:

我有一个 LeafletJS 地图,其中包含许多使用服务工作者缓存的 protobuf 层。这很好用,可以节省大量的加载时间。

我最近添加了一个 Abort Controller 以在更改缩放级别时停止 Fetch 进程,以从浏览器挂起队列中删除当前缩放级别的磁贴,这也节省了大量时间。

我现在的问题是,中止控制器不会对通过 Service Worker 提供的磁贴起作用,而是仅对从服务器获取的磁贴起作用。因此,我的浏览器仍在尝试从服务人员加载当前缩放级别的磁贴,这是不必要的。

下面是我正在使用的 service worker。

var cacheName = 'v1';

function updateCache(request) 
    return caches.open(cacheName).then(cache => 
        return fetch(request,  signal: request.signal ).then(response => 
            const resClone = response.clone();
            if (response.status < 400)
                return cache.put(request, resClone);
            return response;
        );
    );


self.addEventListener('fetch', event => 
    var url = event.request.url 
    if(url.includes('tiles'))  
        event.respondWith(async function() 
            const cachedResponse = await caches.match(event.request);
            if(cachedResponse && !cachedResponse.redirected )
                return cachedResponse
             else

                return fetch(url,  signal: event.request.signal ).then(updateCache(event.request));
                //return fetch(event.request).then(updateCache(event.request));
            
        ());
    
    
);


self.addEventListener('activate', (event) => 
    //console.info('Event: Activate');
    event.waitUntil(
        self.clients.claim(),
        caches.keys().then((cacheNames) => 
            console.log(caches.keys())
            return Promise.all(
                cacheNames.map((cache) => 
                    if (cache !== cacheName) 
                        return caches.delete(cache);
                    
                )
            );
        )
    );
);

self.addEventListener('install', function (event) 
    console.info('Event: Install (ServiceWorker Superseded)');
    self.skipWaiting();
);

我原以为传递请求信号就足够了,但这似乎永远不会触发它取消fetch(request, signal: request.signal )

有人知道如何中止 Service Worker 吗?

【问题讨论】:

【参考方案1】:

这是一个已知问题。 chrome 或 firefox 都没有实现将 AbortSignal 正确发送到 FetchEvent.request.signal。见:

https://bugs.chromium.org/p/chromium/issues/detail?id=823697 https://bugzilla.mozilla.org/show_bug.cgi?id=1394102

我不知道 safari 的行为是什么。

如果规范正确说明是否应该通过该信号探测,存在一些问题:

https://github.com/w3c/ServiceWorker/issues/1544

【讨论】:

嗨,Ben,感谢您提供的链接,使阅读变得有趣,并突破了我的知识极限。我一定会关注这个的。

以上是关于Service Worker 的中止控制器的主要内容,如果未能解决你的问题,请参考以下文章

使用Service Worker和离线缓存Cache

Service Worker概念和应用介绍

转载古典浏览器缓存和Service Worker对比

认识 service worker

Service Worker的缓存时机与缓存策略

在Service Worker中抛出错误“Uncaught(in promise)DOMException”