Was ist Async/Await?
async/await ist eine moderne Syntax in JavaScript, die das Arbeiten mit asynchronem Code deutlich einfacher macht. Es ist syntaktischer Zucker über Promises und macht asynchronen Code lesbarer.
Das Problem mit Callbacks
Früher sahen asynchrone Operationen so aus:
fetchUser(userId, (error, user) => {
if (error) {
console.error(error);
return;
}
fetchPosts(user.id, (error, posts) => {
if (error) {
console.error(error);
return;
}
// Callback Hell! 😱
});
});
Die Lösung: Async/Await
Mit async/await wird der Code viel lesbarer:
async function getUserPosts(userId) {
try {
const user = await fetchUser(userId);
const posts = await fetchPosts(user.id);
return posts;
} catch (error) {
console.error(error);
}
}
Grundlagen
1. Async-Funktionen deklarieren
// Function Declaration
async function myFunction() {
return "Hallo";
}
// Arrow Function
const myFunction = async () => {
return "Hallo";
};
// Eine async-Funktion gibt immer ein Promise zurück
myFunction().then(result => console.log(result)); // "Hallo"
2. Await verwenden
await pausiert die Ausführung der Funktion, bis das Promise aufgelöst ist:
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
}
Wichtig:
awaitkann nur innerhalb vonasync-Funktionen verwendet werden!
Fehlerbehandlung
Mit try/catch
async function fetchUserData(userId) {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error('User nicht gefunden');
}
const user = await response.json();
return user;
} catch (error) {
console.error('Fehler beim Laden:', error.message);
return null;
}
}
Mit .catch()
async function getData() {
const data = await fetch('/api/data').catch(error => {
console.error('Fetch fehlgeschlagen:', error);
return null;
});
return data;
}
Parallele Ausführung
Problem: Sequenziell (langsam)
async function slowFunction() {
const user = await fetchUser(); // 2 Sekunden
const posts = await fetchPosts(); // 2 Sekunden
const comments = await fetchComments(); // 2 Sekunden
// Insgesamt: 6 Sekunden! 😢
}
Lösung: Promise.all() (parallel)
async function fastFunction() {
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchComments()
]);
// Insgesamt: 2 Sekunden!
}
Praktisches Beispiel: API-Calls
async function loadDashboard() {
try {
// Zeige Loading-Spinner
showLoader();
// Lade Daten parallel
const [userData, statsData, notificationsData] = await Promise.all([
fetch('/api/user').then(r => r.json()),
fetch('/api/stats').then(r => r.json()),
fetch('/api/notifications').then(r => r.json())
]);
// Verstecke Loading-Spinner
hideLoader();
// Rendere Dashboard
renderDashboard({ userData, statsData, notificationsData });
} catch (error) {
console.error('Dashboard konnte nicht geladen werden:', error);
showError('Fehler beim Laden des Dashboards');
}
}
Best Practices
✅ Do’s
// Nutze async/await für bessere Lesbarkeit
async function goodExample() {
const data = await fetchData();
return processData(data);
}
// Nutze Promise.all für parallele Operationen
const results = await Promise.all([fetch1(), fetch2()]);
// Behandle Fehler immer
try {
await riskyOperation();
} catch (error) {
handleError(error);
}
❌ Don’ts
// Vergiss nicht 'await'!
async function badExample() {
const data = fetchData(); // ❌ Ohne await!
return data; // Returns Promise, nicht die Daten
}
// Verwende nicht await in Loops (langsam)
for (const item of items) {
await processItem(item); // ❌ Sequenziell
}
// Besser:
await Promise.all(items.map(item => processItem(item)));
Zusammenfassung
asyncmacht eine Funktion asynchron und lässt sie ein Promise zurückgebenawaitpausiert die Ausführung bis das Promise aufgelöst ist- Nutze
try/catchfür Fehlerbehandlung - Nutze
Promise.all()für parallele Operationen - Async/Await macht Code lesbarer als verschachtelte Callbacks