| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/async_function | [Back] [Original] |
Get to know MDN better
Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.
Diese Funktion ist gut etabliert und funktioniert auf vielen Gerten und in vielen Browserversionen. Sie ist seit April 2017 browserbergreifend verfgbar.
Die async function-Deklaration erstellt eine Binding einer neuen asynchronen Funktion mit einem gegebenen Namen. Das await-Schlsselwort ist innerhalb des Funktionskrpers erlaubt, was ermglicht, dass asynchrones, auf Versprechen basierendes Verhalten in einem saubereren Stil geschrieben wird, und die Notwendigkeit vermieden wird, Versprechensketten explizit zu konfigurieren.
Sie knnen auch asynchrone Funktionen mit dem async function Ausdruck definieren.
function resolveAfter2Seconds() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("resolved");
}, 2000);
});
}
async function asyncCall() {
console.log("calling");
const result = await resolveAfter2Seconds();
console.log(result);
// Expected output: "resolved"
}
asyncCall();
async function name(param0) {
statements
}
async function name(param0, param1) {
statements
}
async function name(param0, param1, /* , */ paramN) {
statements
}
Hinweis:
Es darf kein Zeilenumbruch zwischen async und function sein, sonst wird ein Semikolon automatisch eingefgt, was dazu fhrt, dass async zu einem Bezeichner wird und der Rest zu einer function-Deklaration.
nameDer Name der Funktion.
param OptionalDer Name eines formalen Parameters fr die Funktion. Fr die Syntax der Parameter siehe das Funktions-Referenz.
statements OptionalDie Anweisungen, die den Krper der Funktion bilden. Der await-Mechanismus kann verwendet werden.
Eine async function-Deklaration erstellt ein AsyncFunction-Objekt. Jedes Mal, wenn eine asynchrone Funktion aufgerufen wird, gibt sie ein neues Promise zurck, das mit dem Wert aufgelst wird, der von der asynchronen Funktion zurckgegeben wird, oder mit einer Ausnahme abgelehnt wird, die innerhalb der asynchronen Funktion nicht abgefangen wird.
Asynchrone Funktionen knnen null oder mehr await-Ausdrcke enthalten. Await-Ausdrcke lassen versprechensbasierte Funktionen so verhalten, als wren sie synchron, indem sie die Ausfhrung bis zur Erfllung oder Ablehnung des zurckgegebenen Versprechens aussetzen. Der erfllte Wert des Versprechens wird als Rckgabewert des Await-Ausdrucks behandelt. Der Gebrauch von async und await ermglicht die Verwendung gewhnlicher try / catch-Blcke um asynchronen Code.
Hinweis:
Das await-Schlsselwort ist nur innerhalb von asynchronen Funktionen in regulrem JavaScript-Code gltig. Wenn Sie es auerhalb des Krpers einer asynchronen Funktion verwenden, erhalten Sie einen SyntaxError.
await kann eigenstndig mit JavaScript-Modulen verwendet werden.
Hinweis:
Der Zweck von async/await ist die Vereinfachung der Syntax
die zur Nutzung von Promise-basierten APIs notwendig ist. Das Verhalten
von async/await ist hnlich wie die Kombination von Generatoren und
Promises.
Asynchrone Funktionen geben immer ein Versprechen zurck. Wenn der Rckgabewert einer asynchronen Funktion nicht explizit ein Promise ist, wird es implizit in ein Promise gehllt.
Betrachten Sie zum Beispiel folgenden Code:
async function foo() {
return 1;
}
Er ist hnlich wie:
function foo() {
return Promise.resolve(1);
}
Beachten Sie, dass selbst wenn der Rckgabewert einer asynchronen Funktion so behandelt wird, als sei er in Promise.resolve gewickelt, sie nicht gleich sind. Eine asynchrone Funktion wird einen anderen Verweis zurckgeben, wohingegen Promise.resolve denselben Verweis zurckgibt, wenn der gegebene Wert ein Promise ist. Dies kann ein Problem sein, wenn Sie die Gleichheit eines Versprechens und eines Rckgabewerts einer asynchronen Funktion berprfen mchten.
const p = new Promise((res, rej) => {
res(1);
});
async function asyncReturn() {
return p;
}
function basicReturn() {
return Promise.resolve(p);
}
console.log(p === basicReturn()); // true
console.log(p === asyncReturn()); // false
Der Krper einer asynchronen Funktion kann so betrachtet werden, dass er durch null oder mehr await -Ausdrcke aufgeteilt wird. Top-Level-Code, bis einschlielich des ersten Await-Ausdrucks (falls vorhanden), wird synchron ausgefhrt. Auf diese Weise wird eine asynchrone Funktion ohne einen Await-Ausdruck synchron ausgefhrt. Ist jedoch ein Await-Ausdruck im Funktionskrper vorhanden, wird die asynchrone Funktion immer asynchron abgeschlossen.
Zum Beispiel:
async function foo() {
await 1;
}
Er ist ebenfalls gleichbedeutend mit:
function foo() {
return Promise.resolve(1).then(() => undefined);
}
Code nach jedem Await-Ausdruck kann so betrachtet werden, als wrde er in einem .then
Rckruf existieren. Auf diese Weise wird eine Versprechenskette mit jedem Wiedereintritt
in die Funktion progressiv aufgebaut. Der Rckgabewert bildet das letzte Glied in der Kette.
Im folgenden Beispiel warten wir nacheinander auf zwei Versprechen. Der Fortschritt bewegt sich durch
die Funktion foo in drei Phasen.
foo wird synchron ausgefhrt,
mit dem Await-Ausdruck, der mit dem ausstehenden Versprechen konfiguriert ist. Der Fortschritt durch
foo wird dann ausgesetzt und die Kontrolle wird an die Funktion, die
foo aufgerufen hat, zurckgegeben.foo gegeben. Das Ergebnis der ersten Versprechens-Erfllung
(falls es nicht abgelehnt wurde) wird vom Await-Ausdruck zurckgegeben. Hier wird 1
result1 zugewiesen. Der Fortschritt geht weiter und der zweite Await-Ausdruck
wird ausgewertet. Wieder wird der Fortschritt durch foo unterbrochen und die Kontrolle wird
zurckgegeben.foo gegeben. Das Ergebnis der zweiten Versprechensauflsung wird
vom zweiten Await-Ausdruck zurckgegeben. Hier wird 2
result2 zugewiesen. Die Kontrolle geht zum Rckgabewert-Ausdruck (falls vorhanden). Der Standard-Rckgabewert von undefined wird als der Auflsungswert des
aktuellen Versprechens zurckgegeben.async function foo() {
const result1 = await new Promise((resolve) =>
setTimeout(() => resolve("1")),
);
const result2 = await new Promise((resolve) =>
setTimeout(() => resolve("2")),
);
}
foo();
Beachten Sie, wie die Versprechenskette nicht auf einen Schlag aufgebaut wird. Stattdessen wird die Versprechenskette in Phasen konstruiert, da die Kontrolle nacheinander von der asynchronen Funktion abgegeben und dorthin zurckgegeben wird. Als Ergebnis mssen wir uns des Fehlerbehandlungsverhaltens bewusst sein, wenn wir mit gleichzeitigen asynchronen Operationen umgehen.
Zum Beispiel wird im folgenden Code ein unbehandelter Versprechensablehnungsfehler geworfen,
selbst wenn ein .catch-Handler weiter entlang der Versprechenskette
konfiguriert wurde. Das liegt daran, dass p2 nicht in die Versprechenskette "eingebunden" wird, bis
die Kontrolle von p1 zurckkommt.
async function foo() {
const p1 = new Promise((resolve) => setTimeout(() => resolve("1"), 1000));
const p2 = new Promise((_, reject) =>
setTimeout(() => reject(new Error("failed")), 500),
);
const results = [await p1, await p2]; // Do not do this! Use Promise.all or Promise.allSettled instead.
}
foo().catch(() => {}); // Attempt to swallow all errors...
async function-Deklarationen verhalten sich hnlich wie function-Deklarationen sie werden gehoisted an die Spitze ihres Gltigkeitsbereichs und knnen berall in ihrem Gltigkeitsbereich aufgerufen werden, und sie knnen nur in bestimmten Kontexten neu deklariert werden.
function resolveAfter2Seconds() {
console.log("starting slow promise");
return new Promise((resolve) => {
setTimeout(() => {
resolve("slow");
console.log("slow promise is done");
}, 2000);
});
}
function resolveAfter1Second() {
console.log("starting fast promise");
return new Promise((resolve) => {
setTimeout(() => {
resolve("fast");
console.log("fast promise is done");
}, 1000);
});
}
async function sequentialStart() {
console.log("== sequentialStart starts ==");
// 1. Start a timer, log after it's done
const slow = resolveAfter2Seconds();
console.log(await slow);
// 2. Start the next timer after waiting for the previous one
const fast = resolveAfter1Second();
console.log(await fast);
console.log("== sequentialStart done ==");
}
async function sequentialWait() {
console.log("== sequentialWait starts ==");
// 1. Start two timers without waiting for each other
const slow = resolveAfter2Seconds();
const fast = resolveAfter1Second();
// 2. Wait for the slow timer to complete, and then log the result
console.log(await slow);
// 3. Wait for the fast timer to complete, and then log the result
console.log(await fast);
console.log("== sequentialWait done ==");
}
async function concurrent1() {
console.log("== concurrent1 starts ==");
// 1. Start two timers concurrently and wait for both to complete
const results = await Promise.all([
resolveAfter2Seconds(),
resolveAfter1Second(),
]);
// 2. Log the results together
console.log(results[0]);
console.log(results[1]);
console.log("== concurrent1 done ==");
}
async function concurrent2() {
console.log("== concurrent2 starts ==");
// 1. Start two timers concurrently, log immediately after each one is done
await Promise.all([
(async () => console.log(await resolveAfter2Seconds()))(),
(async () => console.log(await resolveAfter1Second()))(),
]);
console.log("== concurrent2 done ==");
}
sequentialStart(); // after 2 seconds, logs "slow", then after 1 more second, "fast"
// wait above to finish
setTimeout(sequentialWait, 4000); // after 2 seconds, logs "slow" and then "fast"
// wait again
setTimeout(concurrent1, 7000); // same as sequentialWait
// wait again
setTimeout(concurrent2, 10000); // after 1 second, logs "fast", then after 1 more second, "slow"
In sequentialStart wird die Ausfhrung fr 2 Sekunden fr das erste
await ausgesetzt und dann nochmal eine Sekunde fr das zweite await. Der
zweite Timer wird nicht erstellt, bis der erste bereits ausgelst hat, sodass der Code nach 3 Sekunden beendet wird.
In sequentialWait werden beide Timer erstellt und dann awaited.
Die Timer laufen gleichzeitig, was bedeutet, dass der Code nach 2 statt 3 Sekunden abgeschlossen wird,
d.h. dem langsamsten Timer.
Die await-Aufrufe laufen jedoch weiterhin in Serie, was bedeutet, dass der zweite
await darauf wartet, dass der erste abgeschlossen wird. In diesem Fall wird das Ergebnis des
schnellsten Timers nach dem langsamsten verarbeitet.
Wenn Sie sicher andere Aufgaben ausfhren mchten, nachdem zwei oder mehr Aufgaben gleichzeitig ausgefhrt wurden und abgeschlossen sind, mssen Sie einen Aufruf zu Promise.all() oder Promise.allSettled() erwarten, bevor die Aufgabe ausgefhrt wird.
Warnung:
Die Funktionen sequentialWait und concurrent1
sind funktional nicht gleichwertig.
In sequentialWait, wenn das Versprechen fast zurckgewiesen wird, bevor das Versprechen
slow erfllt wird, wird ein unbehandelter Versprechensablehnungsfehler
ausgelst, unabhngig davon, ob der Aufrufer eine catch-Klausel konfiguriert hat.
In concurrent1 verdrahtet Promise.all die Versprechenskette
in einem Durchgang, was bedeutet, dass der Vorgang schnell fehlschlgt, unabhngig von der Reihenfolge der
Zurckweisungen der Versprechen, und der Fehler tritt immer innerhalb der konfigurierten
Versprechenskette auf, sodass er auf normale Weise abgefangen werden kann.
Ein API, das ein Promise zurckgibt, wird zu einer Versprechenskette, und es
teilt die Funktion in viele Teile. Betrachten Sie den folgenden Code:
function getProcessedData(url) {
return downloadData(url) // returns a promise
.catch((e) => downloadFallbackData(url)) // returns a promise
.then((v) => processDataInWorker(v)); // returns a promise
}
dieser kann mit einer einzigen asynchronen Funktion wie folgt umgeschrieben werden:
async function getProcessedData(url) {
let v;
try {
v = await downloadData(url);
} catch (e) {
v = await downloadFallbackData(url);
}
return processDataInWorker(v);
}
Alternativ knnen Sie das Versprechen mit catch() verketten:
async function getProcessedData(url) {
const v = await downloadData(url).catch((e) => downloadFallbackData(url));
return processDataInWorker(v);
}
In den beiden umgeschriebenen Versionen bemerken Sie, dass es nach dem
return-Schlsselwort keine await-Anweisung gibt, obwohl das auch gltig wre: Der Rckgabewert einer
asynchronen Funktion wird implizit in Promise.resolve gewickelt - wenn
er nicht bereits selbst ein Versprechen ist (wie in den Beispielen).
| Spezifikation |
|---|
| ECMAScript 2027 LanguageSpecification # sec-async-function-definitions |
AsyncFunctionasync function Ausdruckfunctionfunction*async function*awaitPromiseDer Bauplan fr ein besseres Internet.
Teile dieses Inhalts sind 19982026 von einzelnen mozilla.org-Mitwirkenden. Inhalte sind verfgbar unter einer Creative-Commons-Lizenz.
| Web Proxy Viewer | New URL | Original Page |