tutorials / javascript-async-await

Async/Await in JavaScript verstehen

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: await kann nur innerhalb von async-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

  • async macht eine Funktion asynchron und lässt sie ein Promise zurückgeben
  • await pausiert die Ausführung bis das Promise aufgelöst ist
  • Nutze try/catch für Fehlerbehandlung
  • Nutze Promise.all() für parallele Operationen
  • Async/Await macht Code lesbarer als verschachtelte Callbacks