Start · Sprachen · JavaScript · Referenz · DedicatedWorkerGlobalScope.close()

DedicatedWorkerGlobalScope.close()

Methode

Beendet einen Dedicated Worker aus dem Worker selbst heraus und verwirft alle Aufgaben, die noch in seiner Ereignisschleife warten.

seit JavaScript Baseline: alle Browser (Web Workers) Kategorie: webapi

Signatur

DedicatedWorkerGlobalScope.close()

Beschreibung

Mit close() beendet sich ein Dedicated Worker selbst. Die Methode wird im Worker-Skript aufgerufen, meist einfach als self.close() oder close(), weil self dort auf den DedicatedWorkerGlobalScope zeigt. Alle Aufgaben, die noch in der Ereignisschleife des Workers warten (z. B. eingetroffene Nachrichten, Timer-Callbacks), werden verworfen. Danach nimmt der Worker keine neuen Nachrichten mehr an.

Das Gegenstück im Hauptthread ist Worker.prototype.terminate(). Der Unterschied: terminate() bricht den Worker von außen sofort ab, auch mitten in laufendem Code. close() dagegen ruft der Worker kontrolliert selbst auf, z. B. wenn seine Aufgabe erledigt ist. Vorher kann er noch aufräumen und ein Ergebnis per postMessage() zurückschicken.

Wichtig: close() hält das gerade laufende Skript nicht an. Der synchrone Code nach dem Aufruf läuft bis zum Ende der aktuellen Aufgabe weiter. Neue Aufgaben (Timer, Promise-basierte I/O-Callbacks, Nachrichten) werden danach aber nicht mehr ausgeführt. Deshalb sollte close() in der Regel die letzte Anweisung sein, ggf. mit einem anschließenden return.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined).

Beispiele

Worker beendet sich nach erledigter Berechnung

// worker.js
self.addEventListener('message', (event) => {
  const n = event.data;
  let sum = 0;
  for (let i = 1; i <= n; i++) sum += i;

  // Ergebnis zurücksenden, dann Worker schließen
  self.postMessage({ result: sum });
  self.close();
});

// main.js
const worker = new Worker('worker.js');
worker.addEventListener('message', (e) => {
  console.log('Summe:', e.data.result);
});
worker.postMessage(100);
Summe: 5050

Code nach close() läuft synchron weiter, Timer dagegen nicht

// worker.js
self.close();
console.log('Läuft noch (gleiche Aufgabe)');

setTimeout(() => {
  // Wird NIE ausgeführt, weil die Ereignisschleife verworfen wurde
  console.log('Timer nach close()');
}, 0);

self.postMessage('letzte Nachricht'); // wird noch zugestellt
Läuft noch (gleiche Aufgabe)

Kontrolliertes Herunterfahren per Steuernachricht

// worker.js
let db = null;

self.onmessage = async ({ data }) => {
  if (data.type === 'shutdown') {
    // Aufräumen, bevor der Worker endet
    db?.close();
    self.postMessage({ type: 'bye' });
    self.close();
    return;
  }

  if (data.type === 'open') {
    db = await new Promise((resolve, reject) => {
      const req = indexedDB.open('app-db', 1);
      req.onsuccess = () => resolve(req.result);
      req.onerror = () => reject(req.error);
    });
    self.postMessage({ type: 'ready' });
  }
};

// main.js
const worker = new Worker('worker.js');
worker.onmessage = ({ data }) => console.log('Worker:', data.type);
worker.postMessage({ type: 'open' });
setTimeout(() => worker.postMessage({ type: 'shutdown' }), 1000);
Worker: ready Worker: bye

// Wichtig · Fallstricke

  • Kein sofortiger Abbruch: close() beendet die gerade laufende Aufgabe nicht. Nachfolgender synchroner Code wird noch ausgeführt. Setze danach ein return, wenn kein weiterer Code laufen soll.
  • Ausstehende asynchrone Arbeit geht verloren: Timer, noch nicht verarbeitete Nachrichten und offene fetch-Callbacks werden verworfen. Warte also mit await auf alles Wichtige, bevor du close() aufrufst.
  • Keine Benachrichtigung im Hauptthread: Der Hauptthread bekommt kein Ereignis, wenn sich ein Worker schließt. Schickt der Hauptthread danach noch Nachrichten per postMessage(), werden sie stillschweigend ignoriert. Melde das Ende deshalb vorher selbst per postMessage().
  • Nicht verwechseln mit Worker.terminate() (Hauptthread, sofortiger harter Abbruch). Bei SharedWorkerGlobalScope gibt es ebenfalls close(). Einen Shared Worker beendet der Browser aber erst, wenn keine Verbindungen mehr bestehen.
  • Kompatibilität: wird von allen modernen Browsern unterstützt. Node.js-worker_threads haben eine andere API: Dort ist process.exit() bzw. parentPort.close() zu verwenden.