Rolf B: Async Await und .then()?

Beitrag lesen

Hallo Bertl,

da sind eine ganze Menge Fehler drin, die in ihrer Boshaftigkeit Sauron Konkurrenz machen. Großartiges Anschauungsmaterial!

Grundsätzlich: .then zu verwenden statt await ist eine gute Idee, wenn Du keine async-Triggerfunktion schreiben willst. Du hast aber auch eine Alternative. Deklariere dein Script als type="module". In einem ECMAScript-Modul darfst Du auch auf der Top-Ebene await verwenden. Beachte vom Timing her, dass Scripte mit type="module" als defer-Scripte behandelt werden, d.h. wenn das Script im head steht, wird es nicht wie sonst vor dem Body ausgeführt, sondern am Schluss, gleich vor dem DOMContentLoaded Event. Leider kann ich Dich für ECMAScript-Module nicht an unser Wiki verweisen, es hat dort eine Baustelle wo gerade der erste Spatenstich gemacht ist.

Nun zu deiner Frage:

Eine async-Funktion liefert ein Promise auf ihr Ergebnis. Heißt:

let www = warten();

ergibt ein Promise. Dieses kannst Du awaiten oder mit .then() und .catch() Callbacks für fulfilled oder rejected registrieren.

Und

let www = await warten();

liefert den Wert, den Du aus warten mit return zurück gibst. Hä? Ja genau. Du gibst keinen zurück. In www würde also undefined stehen.

Man müsste also annehmen, dass

await warten().then(console.log("WARUM WARTE ICH NICHT?"));

sich mit einer Fehlermeldung wie "Cannot read properties of undefined (reading 'then')" erbricht. Tut es aber nicht. Und warum? Der Punkt hat höhere Priorität als await, d.h. er ruft das .then() auf dem Promise auf, das warten() zurückgibt und awaitet dann das Promise, das .then() zurückgibt. Und weil aus then immer ein Promise zurückkommt, gibt das keinen Error.

Und warum wartet er nicht?

then erwartet zwei Parameter. Der erste ist ein Callback für den Fall, dass das Promise erfüllt wird und der zweite ist ein Callback für den Fall, dass das Promise zurückgewiesen wird. Beide sind optional, d.h. wenn einer der beiden Parameter undefined ist, wird er kommentarlos ignoriert.

console.log("Huhu") ist aber kein Callback und liefert auch keinen Callback, sondern undefined. Statt dessen wird die log-Methode direkt vor dem Aufruf von then ausgeführt, um ihren Rückgabewert an then zu übergeben. Der ist undefined und wird von then ignoriert, statt einen Fehler wie "Ich will aber einen Callback!" zu erzeugen.

Also:

await warten().then(console.log("WARUM WARTE ICH NICHT?"));

(1) kein await, weil Du das Promise aus warten haben willst
(2) console.log nicht direkt aufrufen, sondern einen Callback übergeben, der loggt

console.log("Go");
warten().then(() => console.log("WARUM GEHT DAS NICHT SCHNELLER?"));

Rolf

--
sumpsi - posui - obstruxi