Von Callbacks und Promises zu Async/Await
async/await
ist ein neuer JavaScript Syntax, um eine asynchrone Funktion zu deklarieren. Es basiert auf Promises, ist aber wesentlich ist einfacher zu lesen.
Eine gründliche Erklärung von Thema Promises soll hier nicht weiter besprochen werden. Wer sich noch nicht mit Promises auskennt, der kann das unter Using Promises gerne nachlesen.
Hier ist eine kurze Auffrischung wie man Promises verwendet:
Promise
Ein Promise repräsentiert ein Wert der Jetzt, in der Zukunft oder (vielleicht) niemals verfügbar ist.
Dabei hat ein Promise folgende Zustände:
- pending — Der Initale Zustand eines Promise
- resolved — Die Operation innerhalb des Promise wurde erfolgreich durchgeführt.
- rejected — Die Operation ist fehlgeschl<gen
Beispiel:
var getRandomWithPromise = error => { return new Promise((resolve, reject) => { setTimeout(() => { if (error) { reject("some error"); return; } resolve(Math.floor(Math.random() * 100)); }, 200); });};
getRandomWithPromise()
definiert ein Promise, welches einen Zufälligen Wert irgendwann zurück liefert. setTimeout()
simuliert hier zum Beispiel einen asynchronen HTTP Request.
Hier ist ein Beispiel wie getRandomWithPromise()
dann verwendet wird.
getRandomWithPromise() .then(result => { console.log(`Your random number is ${result}!`); }) .catch(error => { console.log(`Ups! Something went wrong! Details: ${error}`); });
async/await !
async/await sind die neuen JavaScript Keywords, welche die Asynchrone Programmierung wesentlich vereinfachen.
- async definiert eine Funktion als Asynchron
- await wird verwendet um auf die Erfüllung des Promise zu warten. await kann nur innerhalb einer async Funktion verwendet werden
const getRandomWithAsync = async () => { try { return await getRandomWithPromise(); } catch (error) { return error; }};
Das erste was auffällt ist das async
Keyword bei der Funktionsdeklaration. Dieses deklariert die Funktion getRandomWithAsync()
als asynchron.
Der await
Operator pausiert getRandomWithPromise()
bis der Promise erfüllt wurde.
Erfüllt bedeutet:
- resolved - bedeutet das
await
den erfüllten Wert zurückliefert. - rejected - bedeutet das
await
ein Error/Exception wirft
Da ein Promise nun eine Exception werfen kann, wird der Aufruft in einem try/catch
Block gekapselt.
getRandomWithAsync()
ließt sich nun wie eine sychrone Funktion. Das ist einer der großen Vorteile vom neuen async/await
Syntax! Die Logik vom Code verbessert sich deutlich und komplexe asychrone Operationen lassen sich leicht abbilden.
await
Zur Erinnerung: Der Operator await
kann nur innerhalb einer async
Funktion verwendet werden. Andernfalls ist es ein Syntax Error.
var random = await getRandomWithAsync(); // Syntax Error.
Classes
async
kann auch innerhalb von Klassen verwendet werden.
class Random { async getRandom() { return await getRandomWithPromise(); }}(async function() { var random = new Random(); console.log(`Your random number is ${await random.getRandom()}!`);})();
Mehrere Promises
Was, wenn wir mehr als ein Promise haben, bevor es weiter gehen soll?Wir können es auf zwei Arten lösen - nacheinander oder gleichzeitig.
Nacheinander
(async function() { // Wait for the first promise to be fulfilled. var a = await getRandomWithPromise(); // Wait for the second promise to be fulfilled. var b = await getRandomWithPromise(); console.log(`Your random numbers are ${a} and ${b}!`);})();// [Execution Time] 0.490 ms total
Promise b wird erst ausgeführt wenn Promise a abgeschlossen wurde. So ist die Ausführungszeit die Summe der Ausführungszeiten von Promise a und Promise b.
Das kann zu großen Performanz Probleme führen. Falls also die a und b nicht voneinander abhängig sind, können diese auch gleichzeitig ausgeführt werden
Gleichzeitig
(async function() { // Request the random numbers and save the promises. var aPromise = getRandomWithPromise(); var bPromise = getRandomWithPromise(); var a = await aPromise; var b = await bPromise; console.log(`Your random numbers are ${a} and ${b}!`);})();// [Execution Time] 0.283 ms total
Mit einer kleine Änderungen, laufen beide Promises a und b gleichzeitig und es wird auf beiden gewartet. Die gesamte Ausführungszeit ist die der längsten Ausführungszeit der Promises.
Gleichzeit mit Promise.all
Für einen gleichzeitigen Aufruf können wir auch das bekannte Promise.all
verwenden.Promise.all
hat den Vorteil: Schlägt ein Promise fehl - wird Promise.all
sofort rejected.
Fazit
Durch den async/await
Syntax sieht asynchronen Code wie synchronen Code aus. Dies erleichtert das Lesen und Verstehen des Codes.
Denke daran, der Promise kann Exception werfen. Es ist wichtig, den Code in einen try/catch
Block zu kapseln.
Es können mehrere Promises auf zwei Arten behandelt werden: sequentiell oder gleichzeitig. Gleichzeitig hat den Vorteil, dass Promises parallel ausgeführt werden können.
Mehr Informationen zu Webentwicklung mit Laravel und Wordpress
Ob nach außen für Ihre Kunden oder nach innen für die Verknüpfung mit existierenden Systemen: Wenn es um Web-Technologie geht, sind wir die Spezialisten.