I have read and think I understand:
- What does event.waitUntil do in service worker and why is it needed?
- Service worker error: event already responded to
The just of those answers is that event.waitUntil()
must be called synchronously from the event handler. Which is what I am doing below (in fact it is the only line of the event handler):
The Error
Uncaught (in promise) DOMException: Failed to execute 'respondWith' on 'FetchEvent': The event handler is already finished.
Min reproducible example:
self.addEventListener("fetch", (event) => event.waitUntil(handleFetch(event)));
async function handleFetch(event) {
const response = await runFetch(event);
event.respondWith(response); // <---- here the error is raised
}
async function runFetch(event) {
const response = await fetch(event.request.url);
if (response.ok) {
// Don't await cachePut, allow the response to be returned immediately first.
// Then later it will perform the cachePut promise. Use waitUntil so the Service worker is not killed until the cachePut promise resolves.
event.waitUntil(cachePut(event.request.url, response.clone()));
}
return response
}
async function cachePut(url, response) {
const cache = await caches.open('my-cache');
await cache.put(url, response)
}
Note: It seems okay to call waitUntil
multiple times (calling waitUntil
in a nested sense for cachePut): MDN:
The waitUntil() method must be initially called within the event callback, but after that it can be called multiple times, until all the promises passed to it settle.