Signatur
Beschreibung
Die schreibgeschützte Eigenschaft handled eines FetchEvent liefert ein Promise<undefined>. Es zeigt an, wann der Fetch-Algorithmus des Browsers das Ereignis vollständig behandelt hat, also wann die über respondWith() gelieferte Antwort (oder der normale Netzwerkabruf, falls respondWith() nicht aufgerufen wurde) an die Seite übergeben wurde.
Gedacht ist handled für Nacharbeiten, die erst stattfinden sollen, wenn die Antwort bereits an die Seite ausgeliefert ist: Cache-Einträge aktualisieren, Messwerte oder Logs verschicken, temporäre Ressourcen aufräumen. So verzögert solche Arbeit die Antwort an die Seite nicht.
Das Promise wird erfüllt, wenn die Antwort erfolgreich verarbeitet wurde. Es wird mit einem NetworkError abgelehnt, wenn das an respondWith() übergebene Promise abgelehnt wird, keine gültige Response liefert oder der Abruf anderweitig scheitert.
Weil ein Service Worker jederzeit beendet werden kann, sobald keine Ereignisse mehr offen sind, sollte man auf event.handled immer innerhalb von event.waitUntil() warten. Nur dann bleibt der Worker so lange aktiv, bis die Nacharbeit abgeschlossen ist.
Rückgabewert
undefined erfüllt wird, sobald das Ereignis behandelt wurde. Schlägt die Behandlung fehl, wird es mit einem DOMException vom Typ NetworkError abgelehnt.Beispiele
Nacharbeit erst nach Auslieferung der Antwort
// sw.js
self.addEventListener('fetch', (event) => {
event.respondWith((async () => {
const cached = await caches.match(event.request);
return cached ?? fetch(event.request);
})());
// Worker am Leben halten, bis die Nacharbeit fertig ist
event.waitUntil((async () => {
await event.handled; // Antwort ist jetzt bei der Seite
console.log('Ausgeliefert:', event.request.url);
})());
});
Stale-while-revalidate: Cache im Hintergrund aktualisieren
// sw.js
const CACHE = 'app-v1';
self.addEventListener('fetch', (event) => {
if (event.request.method !== 'GET') return;
event.respondWith((async () => {
const cache = await caches.open(CACHE);
const cached = await cache.match(event.request);
const network = fetch(event.request);
event.waitUntil((async () => {
// Erst ausliefern, dann den Cache aktualisieren
await event.handled;
const fresh = await network;
if (fresh.ok) await cache.put(event.request, fresh.clone());
})());
return cached ?? (await network).clone();
})());
});
Fehlgeschlagene Behandlung protokollieren
// sw.js
self.addEventListener('fetch', (event) => {
if (!event.request.url.endsWith('/api/status')) return;
event.respondWith(fetch(event.request));
event.waitUntil(
event.handled
.then(() => console.log('Status-Anfrage erfolgreich beantwortet'))
.catch((err) => console.warn('Behandlung fehlgeschlagen:', err.name))
);
});
// Wichtig · Fallstricke
- Nur im Service-Worker-Kontext verfügbar:
FetchEventexistiert nicht im Fensterkontext, und Service Worker brauchen HTTPS (oderlocalhost). - Ohne
event.waitUntil()kann der Browser den Worker beenden, bevor die Nacharbeit nachawait event.handledläuft. Die Arbeit geht dann ohne Fehlermeldung verloren. - Wird
await event.handledinnerhalb des anrespondWith()übergebenen Promises vor demreturnaufgerufen, entsteht ein Deadlock: Die Antwort wartet aufhandled, undhandledwartet auf die Antwort. - Ein
Response-Body lässt sich nur einmal lesen. Soll dieselbe Antwort an die Seite gehen und im Cache landen, vorherresponse.clone()verwenden. - Ein abgelehntes
handled-Promise ohnecatch()führt zu einemunhandledrejection-Ereignis im Worker. - Kompatibilität: Chromium seit Version 86, Firefox seit 84, Safari seit etwa 16. In älteren Browsern ist die Eigenschaft
undefined. Vor der Nutzung prüfen, z. B. mitif (event.handled) ….