Start · Sprachen · JavaScript · Referenz · SyncEvent

SyncEvent

Schnittstelle

Stellt das <code>sync</code>-Ereignis der Background Synchronization API dar. Es wird im <code>ServiceWorkerGlobalScope</code> ausgelöst, sobald der Browser wieder eine Netzwerkverbindung hat.

seit JavaScript Chromium-Browser (Chrome/Edge 49+, Opera); nicht i Kategorie: webapi

Signatur

interface SyncEvent extends ExtendableEvent

Beschreibung

SyncEvent ist das Ereignisobjekt, das ein Service Worker beim sync-Ereignis erhält. Die Seite meldet über registration.sync.register(tag) an, dass sie synchronisieren möchte. Der Browser löst das Ereignis aus, sobald eine Netzwerkverbindung besteht. Das kann sofort passieren oder erst später, auch wenn der Tab schon geschlossen ist.

Typische Einsatzfälle sind Offline-Formulare, Chat-Nachrichten oder Warenkorb-Änderungen. Die Daten werden erst lokal gespeichert, meist in IndexedDB, und im sync-Handler an den Server geschickt. So gehen Nutzeraktionen bei schlechter Verbindung nicht verloren.

Die Schnittstelle erbt von ExtendableEvent. Dadurch gibt es event.waitUntil(promise): Damit hält man den Service Worker so lange aktiv, bis die Synchronisation fertig ist. Wird das Promise abgelehnt (rejected), versucht der Browser die Synchronisation später erneut. Dazu kommen zwei eigene, nur lesbare Eigenschaften:

  • tag (string): der Name, der bei register() angegeben wurde.
  • lastChance (boolean): true, wenn der Browser nach diesem Versuch aufgibt.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Konstruktor-Parameter von new SyncEvent(type, options): der Ereignisname, in der Regel "sync".
$options.tag Pflicht string Eindeutiger Name der Synchronisation. Er ist später über event.tag lesbar.
$options.lastChance boolean false Gibt an, ob dies der letzte Versuch des Browsers ist.

Rückgabewert

Typ
SyncEvent
Beschreibung
Der Konstruktor gibt ein neues SyncEvent-Objekt zurück. In der Praxis erzeugt aber der Browser das Objekt und übergibt es an den sync-Handler.

Beispiele

Synchronisation auf der Seite anmelden

// main.js – auf der Seite
const sendeSpaeter = async (nachricht) => {
  await speichereInIndexedDB(nachricht); // eigene Hilfsfunktion
  const registration = await navigator.serviceWorker.ready;
  if ('sync' in registration) {
    await registration.sync.register('nachrichten-senden');
    console.log('Sync registriert');
  } else {
    // Fallback: sofort senden
    await fetch('/api/nachrichten', { method: 'POST', body: JSON.stringify(nachricht) });
  }
};
Sync registriert

sync-Ereignis im Service Worker verarbeiten

// sw.js
self.addEventListener('sync', (event) => {
  if (event.tag === 'nachrichten-senden') {
    event.waitUntil(sendeAusstehendeNachrichten());
  }
});

const sendeAusstehendeNachrichten = async () => {
  const nachrichten = await ladeAusIndexedDB(); // eigene Hilfsfunktion
  for (const n of nachrichten) {
    const res = await fetch('/api/nachrichten', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(n)
    });
    // Ein Fehler lehnt das Promise ab, der Browser versucht es später erneut
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    await loescheAusIndexedDB(n.id);
  }
};

lastChance auswerten

// sw.js
self.addEventListener('sync', (event) => {
  event.waitUntil((async () => {
    try {
      await fetch('/api/sync', { method: 'POST' });
    } catch (err) {
      if (event.lastChance) {
        // Letzter Versuch: Nutzer informieren
        await self.registration.showNotification('Synchronisation fehlgeschlagen', {
          body: 'Bitte die App öffnen und erneut senden.'
        });
      }
      throw err; // erneuten Versuch erlauben
    }
  })());
});

// Wichtig · Fallstricke

Kompatibilität: Nur Chromium-basierte Browser unterstützen die API (Chrome, Edge, Opera, Samsung Internet). Firefox und Safari unterstützen sie nicht. Prüfe deshalb immer mit 'sync' in registration, ob sie verfügbar ist, und sieh einen Fallback vor.

  • Das Ereignis gibt es nur im Service-Worker-Kontext und nur über HTTPS bzw. localhost.
  • Mehrere Anmeldungen mit demselben tag werden zusammengefasst. Die Daten gehören daher in einen eigenen Speicher (IndexedDB), nicht in den Tag.
  • Ohne waitUntil() kann der Browser den Service Worker vorzeitig beenden.
  • Browser begrenzen die Laufzeit (in Chrome etwa wenige Minuten) und die Zahl der Wiederholungen. Danach ist lastChance true.
  • Für wiederkehrende Aufgaben ist PeriodicSyncEvent gedacht (Periodic Background Sync), nicht SyncEvent.