Asynchrone Programmierung in TypeScript: 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

Einführung in die asynchrone Programmierung mit TypeScript

Asynchrone Programmierung ist ein Ansatz zum Schreiben von Code, bei dem zeitaufwändige Operationen (z. B. Serveranfragen, Dateilesevorgänge, Timer) die Ausführung des Hauptprogrammthreads nicht blockieren. In der modernen Webentwicklung ist Asynchronität nicht nur eine Annehmlichkeit, sondern eine Notwendigkeit. JavaScript und TypeScript, als Single-Thread-Sprachen, verwenden die Event Loop zur Verarbeitung asynchroner Operationen.

TypeScript fügt diesem leistungsstarken Paradigma statische Typisierung hinzu, was den Code vorhersehbarer und sicherer macht. In diesem Leitfaden behandeln wir alle Aspekte der asynchronen Programmierung: von klassischen Callbacks bis hin zu modernem async/await mit vollständiger Typisierung.



Grundlagen der Asynchronität: Von Callbacks zu Promises



Das Problem mit Callbacks und die „Callback-Hölle“

Ursprünglich wurde Asynchronität in JavaScript durch Callbacks (Rückruffunktionen) implementiert. Dieser Ansatz führte jedoch schnell zu unleserlichem Code:

function loadData(callback: (data: string) => void) {    setTimeout(() => {        callback("Daten geladen");    }, 1000);}

loadData((data) => { console.log(data); // Verschachtelter Aufruf loadData((data2) => { console.log(data2); });});

Dieser Code ist schwer zu debuggen und zu warten. TypeScript löst das Problem der Verschachtelung nicht, hilft aber bei der Typisierung der Callback-Parameter.



Promises — Rettung aus der Hölle

Ein Promise ist ein Objekt, das sich in einem von drei Zuständen befinden kann: pending (ausstehend), fulfilled (erfolgreich erfüllt) oder rejected (mit Fehler abgelehnt). TypeScript ermöglicht die strikte Typisierung des Datentyps, den das Promise zurückgibt:

function fetchUser(id: number): Promise<User> {    return new Promise((resolve, reject) => {        setTimeout(() => {            if (id > 0) {                resolve({ id, name: "Ivan Petrov" });            } else {                reject(new Error("Ungültige ID"));            }        }, 500);    });}

interface User { id: number; name: string;}

// VerwendungfetchUser(1).then(user => { console.log(user.name); // TypeScript weiß, dass user ein User ist}).catch(error => { console.error(error.message);});

Dank des Generikums Promise<User> garantiert der TypeScript-Compiler, dass wir innerhalb von .then() ein Objekt genau dieses Typs erhalten.



Async/Await: Elegante Asynchronität



Syntax und Typisierung

Die Schlüsselwörter async und await ermöglichen es, asynchronen Code zu schreiben, der wie synchroner Code aussieht. Eine mit async markierte Funktion gibt immer ein Promise zurück:

async function getGreeting(name: string): Promise<string> {    return `Hallo, ${name}!`;}

// Rückgabetyp ist Promise<string>const result: Promise<string> = getGreeting("Welt");

Wichtig zu beachten: Wenn eine async-Funktion kein Promise zurückgibt, verpackt TypeScript es automatisch in ein Promise.



Beispiel mit realer Logik

Betrachten wir ein typisches Szenario – das Abrufen von Daten von einer API und deren Verarbeitung:

interface Post {    userId: number;    id: number;    title: string;    body: string;}

async function fetchPosts(userId: number): Promise<Post[]> { const response = await fetch(`https://jsonplaceholder.typicode.com/posts?userId=${userId}`); if (!response.ok) { throw new Error(`HTTP-Fehler: ${response.status}`); } const data: Post[] = await response.json(); return data;}

async function displayPosts() { try { const posts = await fetchPosts(1); console.log(`Erhalten ${posts.length} Beiträge:`); posts.forEach(post => console.log(`- ${post.title}`));

Blogs

Buchempfehlungen