Wie man eine Antwort aus einem asynchronen Aufruf zurückgibt: Vollständiger Leitfaden für JS

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

„Ich rufe eine Funktion auf, und sie gibt undefined zurück!“ – ein bekanntes Problem?

\n

Stellen Sie sich vor: Sie schreiben Code in JavaScript, machen eine Anfrage an eine API, warten auf Daten… und erhalten als Antwort undefined. Oder noch schlimmer – Promise {<pending>}. Sie lassen die Hände sinken, möchten den Browser schließen und ins Kloster gehen.

\n

Keine Eile. Dieses Problem quält selbst erfahrene Entwickler. Nicht umsonst hat die Frage „How do I return the response from an asynchronous call?“ auf Stack Overflow Tausende von Aufrufen und hunderte Antworten gesammelt. Heute werden wir sie ein für alle Mal klären.

\n

In diesem Artikel erfahren Sie:

\n
    \n
  • Warum return nicht so funktioniert, wie Sie es gewohnt sind
  • \n
  • Wie Sie Asynchronität mit Hilfe von Callbacks, Promises und async/await zähmen
  • \n
  • Welchen Ansatz Sie für Ihr Projekt wählen sollten
  • \n
\n

Los geht‘s!

\n\n

Warum gibt return keine Daten zurück?

\n

Kommen wir gleich zur Sache. Hier ist ein klassisches Beispiel:

\n\n
function getUserData(userId) {\n  fetch(`https://api.example.com/users/${userId}`)\n    .then(response => response.json())\n    .then(data => {\n      return data; // Scheint alles in Ordnung?\n    });\n}\n\nconst user = getUserData(42);\nconsole.log(user); // undefined
\n\n

Kommt Ihnen das bekannt vor? Sie haben return data innerhalb von .then() geschrieben, aber außerhalb erhalten Sie undefined. Warum?

\n

JavaScript ist single-threaded und nicht-blockierend. Wenn Sie fetch aufrufen, wartet es nicht auf die Antwort des Servers. Stattdessen „legt“ es die Ausführung des Callbacks beiseite und geht sofort zur nächsten Zeile über. Und die nächste Zeile ist console.log(user), wobei user noch nicht definiert ist.

\n

Ihre Funktion getUserData wird beendet, bevor die Antwort vom Server eintrifft. Sie gibt nichts zurück (gibt undefined zurück), und die Daten „hängen“ in der Luft.

\n

Wie behebt man das? Es gibt drei Hauptmethoden.

\n\n

Methode 1: Callbacks – der Urvater der Asynchronität

\n

Früher, vor der Einführung von Promises, wurden alle asynchronen Operationen über Callbacks durchgeführt. Sie übergeben eine Funktion, die aufgerufen wird, wenn die Daten eintreffen.

\n\n
function getUserData(userId, callback) {\n  fetch(`https://api.example.com/users/${userId}`)\n    .then(response => response.json())\n    .then(data => {\n      callback(data); // Callback mit Daten aufrufen\n    })\n    .catch(error => {\n      callback(null, error); // Oder Fehler übergeben\n    });\n}\n\n// Verwendung:\ngetUserData(42, (data, error) => {\n  if (error) {\n    console.error('Fehler:', error);\n    return;\n  }\n  console.log('Benutzerdaten:', data);\n});
\n\n

Vorteile: Einfachheit, funktioniert überall.

\n

Nachteile: Wenn Sie mehrere Callbacks ineinander verschachteln, entsteht die „Callback-Hölle“ (callback hell). Der Code wird unlesbar.

\n\n
getUserData(42, (data1) => {\n  getPosts(data1.id, (data2) => {\n    getComments(data2[0].id, (data3) => {\n      // ... und so weiter\n    });\n  });\n});
\n\n

Modernes JavaScript hat sich davon verabschiedet. Aber Callbacks zu verstehen ist notwendig – sie bilden die Grundlage aller anderen Ansätze.

\n\n

Methode 2: Promises – Retter der Lesbarkeit

\n

Ein Promise ist ein Objekt, das ein „Versprechen“ darstellt, in Zukunft einen Wert zurückzugeben. Es hat drei Zustände: pending (ausstehend), fulfilled (erfüllt) und rejected (abgelehnt).

\n

Kehren wir zu unserem Beispiel zurück. Anstelle eines Callbacks geben wir das Promise selbst zurück:

\n\n
function getUserData(userId) {\n  return fetch(`https://api.example.com/users/${userId}`)\n    .then(response => {\n      if (!response.ok) {\n        throw new Error('Netzwerk nicht in Ordnung');\n      }\n      return response.json();\n    });\n}\n\n// Verwendung:\nconst userPromise = getUserData(42);\n\nuserPromise\n  .then(data => {\n    console.log('Benutzerdaten:', data);\n  })\n                

Blogs

Buchempfehlungen