我想使用我的服务工作人员缓存 volatile 数据。我的想法是首先返回可能陈旧的缓存匹配,然后同时触发获取请求并在获取成功时返回该数据。
这是我为要缓存的非 volatile 数据运行的代码:
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
})
})
}
})
)
如何异步返回 cachedResponse
和 fetchResponse
?这可能吗?
更新:
我读过 jack ·阿奇博尔德 (Jake Archibald) 的离线食谱,他在其中谈到 cache then network ,这正是我想要做的,但看来您需要在需要此“缓存然后网络”服务的任何地方添加代码。
我希望有一种方法可以直接从服务 worker 那里做到这一点,尽管我不确定这是否可能,因为一旦你返回缓存的数据,你怎么能在不发出完全相同的请求的情况下返回获取数据再次从页面?
感谢您的帮助!
最佳答案
据我所知,不可能从软件向页面返回两个响应。
例如,您可以使用 PostMessage或Broadcast Channel API s 将消息从 SW 发送到包含新数据的页面。基本上,您将使用 Fetch API 从页面请求某些内容,然后从软件返回缓存的数据,同时发起网络请求,然后使用软件从网络接收到的任何内容刷新缓存,最后如果响应是某些内容new,通过 PostMessage 通知页面“嘿,有新版本可用,请在此处获取:{ data }”。
但是,这可能并不比您在 Offline Cookbook 中看到的更好,而且实际上可能会让您编写更多代码。您可能需要以某种方式管理来自软件的消息(使用新数据)并跟踪页面上要更新的数据等。
如果我理解正确的话,我会做什么:将 Offline Cookbook 的想法推广到一个函数中,该函数可以用来代替简单的 Fetch 请求,并使其返回一个 Promise。浏览代码并用 customFetch() 调用替换 fetch() 调用并将所有缓存 API/SW 逻辑保留在其他位置应该相当简单。
关于javascript - 服务 worker : Return cached response first and fetch response async,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46008897/