Parallelität und Multithreading in TypeScript: von A bis Z

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 A bis Z

In der modernen Webentwicklung rückt die Anwendungsleistung in den Vordergrund. TypeScript, als streng typisierte Erweiterung von JavaScript, bietet Entwicklern leistungsstarke Werkzeuge für die Arbeit mit Asynchronität und Multithreading. In diesem Artikel werden wir die grundlegenden Konzepte der Parallelität erläutern, verstehen, wie der Event Loop funktioniert, und lernen, Worker Threads für echtes Multithreading in Node.js zu nutzen.



1. Asynchronität und Event Loop: Grundlage der Parallelität in TypeScript

Bevor wir über Multithreading sprechen, ist es wichtig zu verstehen, wie TypeScript (und JavaScript) nebenläufige Aufgaben verarbeitet. Grundlage ist der Event Loop – ein Mechanismus, der nicht-blockierende Ein-/Ausgabeoperationen ermöglicht, ohne neue Threads zu erstellen.

Betrachten wir ein einfaches Beispiel für asynchronen Code:

async function fetchData(url: string): Promise<string> {    const response = await fetch(url);    return response.text();}

async function main(): Promise<void> { console.log('Starte Download'); const data = await fetchData('https://api.example.com/data'); console.log('Daten empfangen:', data);}

main();console.log('Code wird weiter ausgeführt');

In diesem Beispiel blockiert await nicht den Hauptthread. Während auf die Antwort des Servers gewartet wird, verarbeitet der Event Loop weiterhin andere Aufgaben, wie die Ausführung von console.log. Dies ist Parallelität – die Fähigkeit, mehrere Aufgaben in einem Zeitraum zu bearbeiten, indem zwischen ihnen umgeschaltet wird.



2. Promises und async/await: Verwaltung asynchroner Operationen

TypeScript bietet praktische syntaktische Konstrukte für die Arbeit mit Asynchronität. Promises sind Objekte, die ein zukünftiges Ergebnis einer asynchronen Operation darstellen. Die Kombination von async/await macht den Code linear und lesbar.

Betrachten wir ein komplexeres Szenario – die parallele Ausführung mehrerer Anfragen:

async function loadMultipleUsers(userIds: number[]): Promise<User[]> {    const promises = userIds.map(id => fetch(`/users/${id}`).then(res => res.json()));    return Promise.all(promises);}

// Verwendungconst users = await loadMultipleUsers([1, 2, 3, 4, 5]);console.log(users); // Alle Benutzer werden parallel geladen

Die Methode Promise.all startet alle Promises gleichzeitig, was die Ausführung im Vergleich zum sequenziellen Laden erheblich beschleunigt. Dies ist ein ideales Beispiel für Parallelität: Aufgaben werden „gleichzeitig“ innerhalb eines Threads ausgeführt.



3. Echtes Multithreading: Worker Threads in Node.js

Obwohl Asynchronität hervorragend für Ein-/Ausgabeoperationen geeignet ist, hilft sie nicht bei CPU-intensiven Aufgaben (Bildverarbeitung, komplexe Berechnungen, Verschlüsselung). Für solche Fälle gibt es in Node.js Worker Threads – echte Betriebssystem-Threads.

Betrachten wir ein Beispiel zur Berechnung einer Fakultät in einem separaten Thread:

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

function factorial(n: number): number { if (n === 0) return 1; return n * factorial(n - 1);}

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

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

function runWorker(n: number): Promise<number> { return new Promise((resolve, reject) => { const worker = new Worker('./worker.ts'); worker.postMessage(n); worker.on('message', resolve); worker.on('error', reject); });}

async function main() { const result = await runWorker(20); console.log('Fakultät von 20:', result);}

main();

Jeder Worker arbeitet in einem eigenen Thread, hat seinen eigenen Event Loop und

Blogs

Buchempfehlungen