Die async function Deklaration leitet eine asynchrone Funktion ein, die ein AsyncFunction Objekt ergibt. Eine asynchrone Funktion arbeitet außerhalb des Kontrollflusses, und teilt ihr Ergebnis durch ein unausgedrücktes, in die Ereignisschleife eingefügtes Promise mit. Die Gestalt des Codes bei einer asynchronen Funktion ähnelt allerdings der der standardmässigen synchronen Funktionen.
Eine async function kann auch durch den async function expression Ausdruck erklärt werden.
The source for this interactive demo is stored in a GitHub repository. If you'd like to contribute to the interactive demo project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
Syntax
async function name([param[, param[, ... param]]]) {
statements
}
Die Parameter
name- Der Name der Funktion.
param- Der Name eines Arguments, welches der Funktion übergeben wird.
statements- Die Ausdrücke, aus denen der Funktionskörper besteht.
Der zurückgegebene Wert
Ein Promise Objekt. Das Promise wird entweder eingehalten (Engl: "resolved"), wobei die Funktion den in dem Funktionskörper berechneten Wert übermittelt, oder verworfen (Engl: "rejected"), in welchem Falle die Funktion einen unbehandelten Fehler aufwirft.
Beschreibung
Eine async Funktion darf einen await Ausdruck enthalten, der die Ausführung der Funktion anhält. Die Funktion wartet auf den zurückgegebenen ("resolved") Wert des Promise, das der await Ausdruck erzeugt, worauf die Funktion ihre Arbeit wieder aufnimmt.
Das Schlüsselwort await gilt nur innerhalb der async Funktionen. Die Verwendung außerhalb solcher Funktion wirft einen SyntaxError auf.
Das Ziel der async/await Funktionen ist zweifach. Erstens vereinfachen sie die Anwendung von Promises im Rahmen eines synchronen Verfahrens. Zweitens ermöglichen sie die kollektive Verarbeitung einer Gruppe von Promises. Genau wie die Promises dem Verhalten von callbacks ("Rückruffunktionen") ähneln, so ähnelt die async/await Methode der Zusammensetzung von Generatoren und Promises.
Beispiele
Einfaches Beispiel
var resolveAfter2Seconds = function() {
//nach 2 Sek. einlösen
console.log("langsames Promise beginnt");
return new Promise(resolve => {
setTimeout(function() {
resolve(20); //"20" taucht als der zurückgegebene Wert der Fkn. auf
console.log("langsames Promise fertig");
}, 2000);
});
};
var resolveAfter1Second = function() {
//nach 1 Sek. einlösen
console.log("schnelles Promise beginnt");
return new Promise(resolve => {
setTimeout(function() {
resolve(10); //"10" taucht als der zurückgegebene Wert der Fkn. auf
console.log("schnelles Promise fertig");
}, 1000);
});
};
var sequentialStart = async function() {
console.log('==ANEINANDER GEREIHT ANFANGEN==');
// Falls der dem await Operator folgende Ausdruck kein Promise ist,
// wird jener Ausdruck in ein eingelöstes ("resolved") Promise umgewandelt
const slow = await resolveAfter2Seconds();
const fast = await resolveAfter1Second();
console.log(slow);
console.log(fast);
}
var concurrentStart = async function() {
console.log('==ZEITGLEICH ANFANGEN mit await==');
const slow = resolveAfter2Seconds(); // die Stoppuhr lässt sich unmittelbar an
const fast = resolveAfter1Second();
console.log(await slow);
console.log(await fast); // wartet auf "slow", obwohl "fast" schon
//fertig ist!
}
var stillConcurrent = function() {
console.log('==ZEITGLEICH ANFANGEN mit Promise.all==');
Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => {
console.log(messages[0]); // langsam
console.log(messages[1]); // schnell
});
}
var parallel = function() {
console.log('==PARALLEL mit Promise.then==');
resolveAfter2Seconds().then((message)=>console.log(message));
resolveAfter1Second().then((message)=>console.log(message));
}
sequentialStart(); // loggt "langsam" nach 2 Sek., dann "schnell" nach einer weiteren Sek.
// wartet, bis das obige Verfahren abschließt
setTimeout(concurrentStart, 4000); // loggt "langsam", dann "schnell" nach 2 Sek.
// wieder warten
setTimeout(stillConcurrent, 7000); // genau wie concurrentStart
// wieder warten
setTimeout(parallel, 10000); // echt parallel: loggt "schnell" nach 1 Sek., dann "langsam" nach einer weitern Sek.
Merke: await mit Promise#then nicht verwechseln
Bei sequentialStart wird die Programmausführung auf 2 Sek. aufgehalten wegen des ersten await, dann wieder auf 1 Sek. wegen des zweiten await. Die zweite Stoppuhr wird erst nach Ablauf der ersten Stoppuhr erstellt.
Bei concurrentStart werden beide Stoppuhren gleichzeitig erstellt, dann in await versetzt. Obwohl beide Uhren nebeneinander laufen, laufen die await Abrufe serienweise. Das bedeutet, dass die zweite await Anweisung auf Ablauf der ersten wartet. Die Laufzeit dieses Abschnitts lautet daher 2--nicht 3--Sekunden, weil das langsamere Verfahren 2 Sek. braucht. Das Gleiche ereignet sich bei stillConcurrent, welcher Abschnitt die Promise.all Methode verwendet.
Wenn man auf mehrfache Promises parallel warten (await) will, muss man Promise#then verwenden, gerade wie die parallel Funktion am Ende dieses Beispiels.
Umschreiben einer Promise-Kette mittels einer async Funktion
Eine API die ein Promise zurückgibt resultiert in einer vielteiligen Promise-Kette. Man beachte den folgenden Code:
function getProcessedData(url) {
return downloadData(url) // returns a promise
.catch(e => {
return downloadFallbackData(url) // returns a promise
})
.then(v => {
return processDataInWorker(v); // returns a promise
});
}
das kann mit einer async Funktion folgendermaßen umgeschrieben werden:
async function getProcessedData(url) {
let v;
try {
v = await downloadData(url);
} catch(e) {
v = await downloadFallbackData(url);
}
return processDataInWorker(v);
}
Im obigen Beispiel ist zu beachten, dass es keinen await Ausdruck auf dem return Ausdruck gibt, weil der Rückgabewert einer async function implizit im Promise.resolve eingeschlossen ist.
Spezifikationen
| Specification | Status | Comment |
|---|---|---|
| ECMAScript Latest Draft (ECMA-262) Die Definition von 'async function' in dieser Spezifikation. |
Entwurf | Initial definition in ES2017. |
| ECMAScript 2017 (ECMA-262) Die Definition von 'async function' in dieser Spezifikation. |
Standard |
Browserkompatibilität
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
async function | Chrome Vollständige Unterstützung 55 | Edge Vollständige Unterstützung 15 | Firefox Vollständige Unterstützung 52 | IE Keine Unterstützung Nein | Opera Vollständige Unterstützung 42 | Safari Vollständige Unterstützung 10.1 | WebView Android Vollständige Unterstützung Ja | Chrome Android Vollständige Unterstützung 55 | Firefox Android Vollständige Unterstützung 52 | Opera Android Vollständige Unterstützung 42 | Safari iOS Vollständige Unterstützung 10.3 | Samsung Internet Android Vollständige Unterstützung 6.0 | nodejs
Vollständige Unterstützung
7.6.0
|
Legende
- Vollständige Unterstützung
- Vollständige Unterstützung
- Keine Unterstützung
- Keine Unterstützung
- Benutzer muss dieses Feature explizit aktivieren.
- Benutzer muss dieses Feature explizit aktivieren.