Signatur
Beschreibung
ExtendableEvent ist das Basis-Interface für Ereignisse, die im globalen Geltungsbereich eines Service Workers (ServiceWorkerGlobalScope) ausgelöst werden. Normalerweise darf der Browser einen Service Worker beenden, sobald ein Ereignis-Handler fertig ist. Über die Methode waitUntil() teilst du dem Browser mit, dass noch asynchrone Arbeit läuft und der Worker bis zu deren Abschluss am Leben bleiben soll.
Im Lebenszyklus spielt das eine zentrale Rolle:
install: Der Worker gilt erst als installiert, wenn alle Promises erfüllt sind. Wird ein Promise zurückgewiesen, schlägt die Installation fehl und der Worker wird verworfen – ideal zum Vorab-Cachen (Precaching) von Ressourcen.activate: Der Browser hält funktionale Ereignisse wiefetchundpushzurück, bis die Aktivierung abgeschlossen ist – ideal zum Aufräumen alter Caches oder zur Datenbank-Migration.
Mehrere Ereignisse erben von ExtendableEvent, u. a. FetchEvent, ExtendableMessageEvent, PushEvent, NotificationEvent, SyncEvent und InstallEvent. Eigene Instanzen erzeugt man mit new ExtendableEvent(type, options), was in der Praxis vor allem in Tests vorkommt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Konstruktor-Parameter: Name des Ereignisses, z. B. "install" oder "activate". |
|
| $options | object | {} | Konstruktor-Parameter: Wie bei Event – bubbles, cancelable, composed (jeweils boolean, Standard false). |
Rückgabewert
ExtendableEvent-Instanz. Die Instanzmethode waitUntil(promise) gibt undefined zurück.Beispiele
Precaching im install-Ereignis
// sw.js
const CACHE_NAME = 'app-v2';
const ASSETS = ['/', '/index.html', '/styles.css', '/app.js'];
self.addEventListener('install', (event) => {
// Installation erst abschließen, wenn alle Dateien im Cache liegen
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => cache.addAll(ASSETS))
);
});
Alte Caches im activate-Ereignis aufräumen
// sw.js
const CURRENT = 'app-v2';
self.addEventListener('activate', (event) => {
event.waitUntil((async () => {
const keys = await caches.keys();
await Promise.all(
keys.filter((key) => key !== CURRENT).map((key) => caches.delete(key))
);
// Offene Seiten sofort übernehmen
await self.clients.claim();
console.log('Aktivierung abgeschlossen');
})());
});
Instanziierung und Typprüfung
// Im Service Worker ist ExtendableEvent global verfügbar
const evt = new ExtendableEvent('custom-task');
console.log(evt instanceof Event, evt.type);
self.addEventListener('fetch', (event) => {
// FetchEvent erbt von ExtendableEvent
console.log(event instanceof ExtendableEvent);
});
// Wichtig · Fallstricke
- Synchron aufrufen:
waitUntil()muss während der Ereignis-Verarbeitung (synchron im Handler) aufgerufen werden. Ein späterer Aufruf, etwa nach einemawaitohne weitere offenen Promises, wirft eineInvalidStateError-DOMException. - Fehler in install: Ein einziger fehlgeschlagener Eintrag in
cache.addAll()weist das ganze Promise zurück – die Installation scheitert. Nur wirklich nötige Ressourcen vorab cachen. - Keine Endlos-Verlängerung: Browser setzen Zeitlimits. Lang laufende Promises können trotzdem zum Beenden des Workers führen.
- Kompatibilität: Nur im Service-Worker-Kontext und nur in sicheren Kontexten (HTTPS bzw.
localhost) verfügbar. Im Fenster-Kontext (window) existiertExtendableEventnicht. - Selbst erzeugte Instanzen, die per
dispatchEvent()ausgelöst werden, verlängern die Lebensdauer des Workers nicht.