Parallelität und Multithreading in TypeScript: Fortgeschrittenes Niveau
\n\nIn der modernen Webentwicklung und serverseitigen Programmierung sind Leistung und Reaktionsfähigkeit von Anwendungen von entscheidender Bedeutung. TypeScript, als Erweiterung von JavaScript, hat dessen Single-Thread-Ausführungsmodell (Event Loop) geerbt. Für ressourcenintensive Aufgaben (Bildverarbeitung, Kryptographie, komplexe Berechnungen) reicht Asynchronität allein jedoch nicht aus. Auf fortgeschrittenem Niveau muss ein Entwickler verstehen, wie man echte Multithreading-Fähigkeiten und sichere Arbeit mit gemeinsam genutztem Speicher organisiert. In diesem Artikel werden wir die wichtigsten Mechanismen behandeln: Web Workers (Browser), Worker Threads (Node.js), SharedArrayBuffer und Atomics.
\n\n1. Web Workers: Parallelität im Browser
\n\nWeb Workers sind die primäre Methode, um Code in einem separaten Thread in der Browserumgebung auszuführen. Ein Worker hat keinen Zugriff auf das DOM, kann aber schwere Berechnungen durchführen, ohne den Hauptthread (UI) zu blockieren.
\n\nDas Erstellen eines Workers in TypeScript erfordert die Kompilierung einer separaten Datei. Betrachten wir ein Beispiel: die Berechnung großer Fibonacci-Zahlen.
\n\nDatei worker.ts (wird zu worker.js kompiliert):
\n// worker.ts\nself.onmessage = (event: MessageEvent<number>) => {\n const n = event.data;\n const fib = (num: number): number => {\n if (num <= 1) return num;\n return fib(num - 1) + fib(num - 2);\n };\n const result = fib(n);\n self.postMessage(result);\n};\n\nDatei main.ts:
\n// main.ts\nconst worker = new Worker(new URL('./worker.js', import.meta.url));\n\nworker.postMessage(40);\n\nworker.onmessage = (event: MessageEvent<number>) => {\n console.log(`Ergebnis: ${event.data}`); // Ausgabe nach Abschluss\n worker.terminate();\n};\n\nworker.onerror = (error) => {\n console.error('Worker-Fehler:', error.message);\n};\n\nWichtige Nuancen:
\n- \n
- Der Worker wird in einem separaten Thread ausgeführt, hat aber keinen Zugriff auf die globalen Variablen des Hauptthreads. \n
- Die Datenübergabe erfolgt durch Kopieren (strukturelles Klonen). Für große Datenmengen verwenden Sie Transferable objects (z. B. ArrayBuffer). \n
- Für TypeScript ist es zwingend erforderlich, Typen in Nachrichten anzugeben, um Laufzeitfehler zu vermeiden. \n
2. Worker Threads: Multithreading in Node.js
\n\nFür die serverseitige Umgebung Node.js ist das Äquivalent zu Web Workers das Modul worker_threads. Es ermöglicht die Erstellung isolierter Threads mit eigenem Speicher (V8 isolate). Dies ist ideal für CPU-intensive Operationen wie Hashing oder JSON-Parsing.
Beispiel: Erstellen eines Workers zum Passwort-Hashing (worker.ts):
\n// crypto-worker.ts\nimport { parentPort, workerData } from 'worker_threads';\nimport { createHash } from 'crypto';\n\nif (parentPort) {\n const { password, salt } = workerData;\n const hash = createHash('sha256')\n .update(password + salt)\n .digest('hex');\n parentPort.postMessage(hash);\n}\n\nHauptdatei (main.ts):
\n// main.ts\nimport { Worker } from 'worker_threads';\nimport path from 'path';\n\nfunction hashPassword(password: string, salt: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const worker = new Worker(path.resolve(__dirname, 'crypto-worker.js'), {\n workerData: { password, salt }\n });\n\n worker.on('message', resolve);\n worker.on('error', reject);\n worker.on('exit', (code) => {\n if (code !== 0) reject(new Error(`Worker mit Code ${code} beendet`));\n });\n });\n}\n\n(async () => {\n const hash = await hashPassword('mySecret', 'randomSalt');\n console.log(`Hash: ${hash}`);\n})();\n\nWichtige Unterschiede zu Web Workers:
\n- \n
- Läuft in Node.js, hat Zugriff auf das Dateisystem und den Prozess. \n
- Datenübergabe über