diff --git a/files/en-us/web/api/service_worker_api/using_service_workers/index.md b/files/en-us/web/api/service_worker_api/using_service_workers/index.md index 8ab2b736c3eb208..de25aa50ed9d777 100644 --- a/files/en-us/web/api/service_worker_api/using_service_workers/index.md +++ b/files/en-us/web/api/service_worker_api/using_service_workers/index.md @@ -204,18 +204,18 @@ const putInCache = async (request, response) => { await cache.put(request, response); }; -const cacheFirst = async (request) => { +const cacheFirst = async (request, event) => { const responseFromCache = await caches.match(request); if (responseFromCache) { return responseFromCache; } const responseFromNetwork = await fetch(request); - putInCache(request, responseFromNetwork.clone()); + event.waitUntil(putInCache(request, responseFromNetwork.clone())); return responseFromNetwork; }; self.addEventListener("fetch", (event) => { - event.respondWith(cacheFirst(event.request)); + event.respondWith(cacheFirst(event.request, event)); }); ``` @@ -223,7 +223,7 @@ If the request URL is not available in the cache, we request the resource from t Cloning the response is necessary because request and response streams can only be read once. In order to return the response to the browser and put it in the cache we have to clone it. So the original gets returned to the browser and the clone gets sent to the cache. They are each read once. -What might look a bit weird is that the promise returned by `putInCache()` is not awaited. But the reason is that we don't want to wait until the response clone has been added to the cache before returning a response. +What might look a bit weird is that the promise returned by `putInCache()` is not awaited. The reason is that we don't want to wait until the response clone has been added to the cache before returning a response. However, we do need to call `event.waitUntil()` on the promise, to make sure the service worker doesn't terminate before the cache is populated. The only trouble we have now is that if the request doesn't match anything in the cache, and the network is not available, our request will still fail. Let's provide a default fallback so that whatever happens, the user will at least get something: @@ -233,7 +233,7 @@ const putInCache = async (request, response) => { await cache.put(request, response); }; -const cacheFirst = async ({ request, fallbackUrl }) => { +const cacheFirst = async ({ request, fallbackUrl, event }) => { // First try to get the resource from the cache const responseFromCache = await caches.match(request); if (responseFromCache) { @@ -246,7 +246,7 @@ const cacheFirst = async ({ request, fallbackUrl }) => { // response may be used only once // we need to save clone to put one copy in cache // and serve second one - putInCache(request, responseFromNetwork.clone()); + event.waitUntil(putInCache(request, responseFromNetwork.clone())); return responseFromNetwork; } catch (error) { const fallbackResponse = await caches.match(fallbackUrl); @@ -268,6 +268,7 @@ self.addEventListener("fetch", (event) => { cacheFirst({ request: event.request, fallbackUrl: "/gallery/myLittleVader.jpg", + event, }), ); }); @@ -308,7 +309,12 @@ const putInCache = async (request, response) => { await cache.put(request, response); }; -const cacheFirst = async ({ request, preloadResponsePromise, fallbackUrl }) => { +const cacheFirst = async ({ + request, + preloadResponsePromise, + fallbackUrl, + event, +}) => { // First try to get the resource from the cache const responseFromCache = await caches.match(request); if (responseFromCache) { @@ -319,7 +325,7 @@ const cacheFirst = async ({ request, preloadResponsePromise, fallbackUrl }) => { const preloadResponse = await preloadResponsePromise; if (preloadResponse) { console.info("using preload response", preloadResponse); - putInCache(request, preloadResponse.clone()); + event.waitUntil(putInCache(request, preloadResponse.clone())); return preloadResponse; } @@ -329,7 +335,7 @@ const cacheFirst = async ({ request, preloadResponsePromise, fallbackUrl }) => { // response may be used only once // we need to save clone to put one copy in cache // and serve second one - putInCache(request, responseFromNetwork.clone()); + event.waitUntil(putInCache(request, responseFromNetwork.clone())); return responseFromNetwork; } catch (error) { const fallbackResponse = await caches.match(fallbackUrl); @@ -379,6 +385,7 @@ self.addEventListener("fetch", (event) => { request: event.request, preloadResponsePromise: event.preloadResponse, fallbackUrl: "/gallery/myLittleVader.jpg", + event, }), ); });