Web Worker in TypeScript

Web Worker in TypeScript

Dieser Artikel erklärt Web Worker in TypeScript.

Sie können das Konzept der Web Worker und verschiedene Anwendungstipps mit Beispielen lernen.

YouTube Video

Worker in TypeScript

In TypeScript ist ein Worker ein Mechanismus zur Durchführung von Bearbeitungen im Hintergrund, getrennt vom Hauptthread, unter Nutzung der JavaScript-Web-Worker-API. Dies ermöglicht es, umfangreiche Berechnungen und asynchrone Aufgaben auszuführen, ohne die Funktionalität der Benutzeroberfläche zu beeinträchtigen.

Ein Worker arbeitet parallel zum Hauptthread (UI-Thread) und kann Daten zwischen Threads über Nachrichten austauschen. Auch in TypeScript können Sie Worker nutzen und dabei typsicheren Code schreiben.

Grundlegende Verwendung von Worker

  1. Einen Worker erstellen

    Erstellen Sie eine Worker-Instanz und führen Sie das angegebene Skript aus. Normalerweise wird das Skript in einer separaten Datei definiert.

  2. Nachrichtenaustausch

    Senden und empfangen Sie Nachrichten zwischen dem Hauptthread und dem Worker-Thread mit postMessage und onmessage.

Beispiel: Grundlegende Implementierung eines Workers

  1. worker.ts: Skript für den Worker
1// worker.ts
2self.onmessage = (event) => {
3    const data = event.data;
4    const result = data.num1 + data.num2;
5    self.postMessage(result); // Return the result to the main thread
6};
  1. main.ts: Skript zur Nutzung des Workers im Hauptthread
 1// main.ts
 2const worker = new Worker(
 3    new URL('./worker.ts', import.meta.url),
 4    { type: 'module' }
 5);
 6
 7worker.onmessage = (event) => {
 8    console.log("Result from worker:", event.data); // Receive message from the worker
 9};
10
11worker.postMessage({ num1: 10, num2: 20 }); // Send message to the worker
  • In diesem Beispiel läuft worker.ts in einem separaten Thread, berechnet die Summe von num1 und num2 und gibt sie an den Hauptthread zurück. Der Hauptthread empfängt das Ergebnis und gibt es auf der Konsole aus.
  • Wenn Sie type: 'module' angeben, wird das Worker-Skript als ES-Modul interpretiert, sodass Sie import und export verwenden können. Dadurch können Sie Modulstrukturen ohne die herkömmliche Verwendung von importScripts() handhaben.

Zu beachtende Punkte bei der Verwendung von Workern in TypeScript

Typdefinitionen hinzufügen

Definieren Sie in TypeScript Datentypen, um eine typsichere Interaktion beim Senden und Empfangen von Nachrichten zu gewährleisten.

 1// Define data types
 2interface WorkerData {
 3    num1: number;
 4    num2: number;
 5}
 6
 7interface WorkerResult {
 8    result: number;
 9}
10
11// worker.ts
12self.onmessage = (event: MessageEvent<WorkerData>) => {
13    const data = event.data;
14    const result = data.num1 + data.num2;
15    const message: WorkerResult = { result };
16    self.postMessage(message); // Send the result in a type-safe manner
17};
18
19// main.ts
20const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
21
22// Type the event from the worker
23worker.onmessage = (event: MessageEvent<WorkerResult>) => {
24  console.log("Result from worker:", event.data); // event.data is number
25};
26
27// Send typed data to the worker
28const message: WorkerData = { num1: 10, num2: 20 };
29worker.postMessage(message);
  • Indem Sie den Typparameter von MessageEvent angeben, können Sie den zu empfangenden Datentyp klar definieren. Dies ermöglicht den Austausch von Daten mit Typsicherheit.

Einrichten von Webpack oder Vite

Beim Verwenden von Worker in TypeScript können Bundler wie Webpack oder Vite erforderlich sein. Mit diesen Tools können Sie das Worker-Skript korrekt bündeln und es vom Hauptthread aus verfügbar machen.

Wenn Sie beispielsweise Vite verwenden, nutzen Sie import.meta.url, um den Worker korrekt zu importieren.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
  • Dies stellt sicher, dass das gebündelte Worker-Skript korrekt geladen wird, wodurch Verarbeitung mit Worker ermöglicht wird.

Überlegungen zu Nachrichtenübermittlung und Parallelität

  1. Datenkopieren

    Beim Senden und Empfangen von Nachrichten zwischen dem Hauptthread und dem Worker-Thread werden Daten kopiert. Beim Umgang mit komplexen Daten wie Objekten muss die Effizienz berücksichtigt werden. Der häufige Austausch großer Datenmengen kann die Leistung beeinträchtigen.

  2. Transferable-Objekte

    Einige Objekte, wie zum Beispiel ArrayBuffer, werden als Transferable Objekte bezeichnet. Transferable Objekte können während der Nachrichtenübermittlung an den Worker übertragen werden, anstatt kopiert zu werden. Dies ermöglicht es, den Overhead des Datenkopierens zu vermeiden.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2
3const buffer = new ArrayBuffer(1024);
4worker.postMessage(buffer, [buffer]); // Transfer ownership to the Worker
5
6console.log(buffer.byteLength); // 0 (ownership moved)
  • Wenn [buffer] als zweites Argument an worker.postMessage() übergeben wird, wird der buffer an den Worker übertragen, anstatt kopiert zu werden.

  • Danach wird der buffer im Haupt-Thread leer (mit byteLength 0) und kann nur noch vom Worker verwendet werden.

Einen Worker beenden

Der Worker sollte nach der Nutzung beendet werden, um den Speicherverbrauch zu minimieren. Sie können einen Worker mit der Methode terminate beenden.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2// ...
3
4worker.terminate(); // Terminate the Worker
  • Dieser Code beendet den Worker mit der Methode terminate.

Fehlerbehandlung im Worker

Wenn ein Fehler innerhalb eines Worker auftritt, können Sie diesen mit dem onerror-Ereignis behandeln.

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2
3worker.onerror = (error) => {
4    console.error("Error in Worker:", error.message);
5};
  • Dieser Code fängt Fehler ab, die im Worker auftreten, und behandelt sie mit dem Ereignis onerror.

Zusammenfassung

Durch die Verwendung von Worker in TypeScript können Sie aufwendige Aufgaben im Hintergrund ausführen, während der Hauptthread flüssig bleibt. Durch die Nutzung von Typdeklarationen können Nachrichtenaustausche ebenfalls typsicher durchgeführt werden. Durch die Beachtung von Datenaustausch und Thread-Management können Leistungsverbesserungen und effiziente Parallelität erreicht werden.

Sie können den obigen Artikel mit Visual Studio Code auf unserem YouTube-Kanal verfolgen. Bitte schauen Sie sich auch den YouTube-Kanal an.

YouTube Video