Parallelität und Multithreading in TypeScript: Ein vollständiger Leitfaden

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Parallelität und Multithreading in TypeScript: Von der Theorie zur Praxis



Moderne Webanwendungen stehen zunehmend vor der Notwendigkeit, große Datenmengen zu verarbeiten und rechenintensive Operationen durchzuführen, ohne die Benutzeroberfläche zu blockieren. TypeScript, als Erweiterung von JavaScript, erbt dessen Single-Thread-Ausführungsmodell, bietet aber dennoch leistungsstarke Werkzeuge zur Organisation von Parallelität und Multithreading. In diesem Artikel werden wir uns ansehen, wie Sie diese Möglichkeiten effektiv in Ihren Projekten nutzen können.



Verständnis von Parallelität und Multithreading



Bevor wir uns in den Code vertiefen, ist es wichtig, zwei Schlüsselbegriffe voneinander abzugrenzen:



  • Parallelität (Concurrency) — die Fähigkeit eines Systems, mehrere Aufgaben in überlappenden Zeiträumen zu bearbeiten, aber nicht unbedingt gleichzeitig. Dies wird durch schnellen Kontextwechsel erreicht.
  • Multithreading — die parallele Ausführung mehrerer Threads auf verschiedenen Prozessorkernen. In Node.js wird dies durch Worker Threads realisiert.


TypeScript läuft in der Node.js-Umgebung, wo der Hauptthread Ereignisse über die Event Loop verarbeitet. Für schwere Berechnungen kann dies zu einem Engpass werden.



Asynchronität und Promise: Die Grundlage der Parallelität



Die grundlegende Ebene der Parallelität in TypeScript basiert auf async/await und Promise. Diese Mechanismen ermöglichen es, den Hauptthread während des Wartens auf I/O-Operationen nicht zu blockieren.



// Beispiel für asynchrones Laden von Dateninterface User {  id: number;  name: string;}

async function fetchUser(id: number): Promise<User> { const response = await fetch(`https://api.example.com/users/${id}`); return response.json();}

// Paralleler Start mehrerer Anfragenasync function loadUsers(): Promise<User[]> { const userIds = [1, 2, 3, 4, 5]; const promises = userIds.map(id => fetchUser(id)); return Promise.all(promises);}

loadUsers().then(users => { console.log('Geladene Benutzer:', users.length);});


Promise.all startet alle Promises gleichzeitig, aber sie werden in einem einzigen Thread ausgeführt. Dies ist ideal für I/O-Aufgaben, aber nicht geeignet für CPU-intensive Operationen.



Worker Threads: Echtes Multithreading



Für die Ausführung schwerer Berechnungen ohne Blockierung des Hauptthreads verwenden Sie Worker Threads. Dies ist ein integriertes Modul von Node.js, das separate Threads mit eigenem Speicher erstellt.



Erstellen wir ein Beispiel zur Berechnung von Fibonacci-Zahlen in einem separaten Thread:



// fibonacci.worker.tsimport { parentPort } from 'worker_threads';

function fibonacci(n: number): number { if (n <= 1) return n; return fibonacci(n - 1) + fibonacci(n - 2);}

parentPort?.on('message', (n: number) => { const result = fibonacci(n); parentPort?.postMessage(result);});


// main.tsimport { Worker } from 'worker_threads';import path from 'path';

function runFibonacciInWorker(n: number): Promise<number> { return new Promise((resolve, reject) => { const worker = new Worker(path.resolve(__dirname, 'fibonacci.worker.ts')); worker.postMessage(n); worker.on('message', resolve); worker.on('error', reject); worker.on('exit', (code) => { if (code !== 0) reject(new Error(`Worker stopped with exit code ${code}`)); }); });}

async function main() { console.time('fibonacci'); const result = await runFibonacciInWorker(40); console.timeEnd('fibonacci'); console.log(`Fibonacci(40) = ${result}`);}

main();


Beachten Sie: Zum Ausführen von TypeScript-Workern ist eine Kompilierung in JavaScript erforderlich. Sie können ts-node oder eine vorherige Kompilierung verwenden.



SharedArrayBuffer: Gemeinsamer Speicher zwischen Threads



Wenn Threads große Datenmengen austauschen müssen

Blogs

Buchempfehlungen