我想用我的服务人员缓存易失性数据。我的想法是先返回可能已过时的缓存匹配,然后同时触发提取请求,如果/成功则返回该数据。

这是我为要缓存的非易失性数据运行的代码:

return e.respondWith(
    caches.match(request.url).then(function(cacheResponse) {
        // Found it in the cache
        if (cacheResponse) {
            console.log('[ServiceWorker] Found it in Cache')
            return cacheResponse
        // Not in the cache
        } else {
            console.log('[ServiceWorker] Not in Cache')
            return fetch(request).then(function(fetchResponse) {
                console.log('[ServiceWorker] Fetched from API', fetchResponse)
                // don't cache errors
                if (!(fetchResponse && fetchResponse.status === 200)) {
                    console.log('[ServiceWorker] Fetch error, no cache')
                    return fetchResponse
                }
                return caches.open(cacheName).then(function(cache) {
                    cache.put(request.url, fetchResponse.clone())
                    console.log('[ServiceWorker] Fetched and Cached Data', request.url)
                    return fetchResponse
                })
            })
        }
    })
)


我如何异步返回cachedResponsefetchResponse?这可能吗?



更新:

我已经读过杰克·阿奇博尔德(Jake Archibald)的离线食谱,他在其中谈论cache then network,这正是我想要做的,但是看来您需要在所有需要拨打电话的地方添加代码,然后才需要此“缓存然后网络”服务。

我希望有一种方法可以直接从服务工作者处执行此操作,尽管我不确定是否可行,因为一旦返回缓存数据,又如何返回获取数据而又不会再次发出完全相同的请求,页?

谢谢您的帮助!

最佳答案

据我所知,不可能从软件返回两个响应到页面。

例如,您可以做的是使用PostMessageBroadcast Channel API将带有新数据的消息从SW发送到页面。基本上,您将使用Fetch API从页面中请求某些内容,然后从SW返回缓存的数据,并同时发起网络请求,然后使用从网络接收到的任何SW刷新缓存,最后,如果响应是某种新增,请通过PostMessage通知页面“嘿,有可用的新版本,请在此处使用:{data}”。

但是,这可能不会比您在《离线食谱》中看到的更好,并且可能实际上使您编写了更多代码。您将需要以某种方式管理来自SW的消息(包含新数据),并跟踪页面上要更新的数据等。

如果我对您的理解正确,该怎么办:在一个可以代替简单的Fetch请求使用的函数中推广Offline Cookbook的想法,并使其返回Promise。遍历代码并将fetch()调用替换为customFetch()调用,并将所有Caches API / SW逻辑保留在其他位置,应该相当简单。

关于javascript - ServiceWorkers:首先返回缓存的响应并异步获取响应,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46008897/

10-12 05:36