Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

Experiment: Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten.

async function

BaselineWidely available

Dieasync function-Deklaration erstellt eineBinding einer neuen asynchronen Funktion mit einem gegebenen Namen. Dasawait-Schlüsselwort ist innerhalb des Funktionskörpers erlaubt, was ermöglicht, dass asynchrones, auf Versprechen basierendes Verhalten in einem saubereren Stil geschrieben wird, und die Notwendigkeit vermieden wird, Versprechensketten explizit zu konfigurieren.

Sie können auch asynchrone Funktionen mit demasync function Ausdruck definieren.

Probieren Sie es aus

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();

Syntax

js
async function name(param0) {  statements}async function name(param0, param1) {  statements}async function name(param0, param1, /* …, */ paramN) {  statements}

Hinweis:Es darf kein Zeilenumbruch zwischenasync undfunction sein, sonst wird ein Semikolonautomatisch eingefügt, was dazu führt, dassasync zu einem Bezeichner wird und der Rest zu einerfunction-Deklaration.

Parameter

name

Der Name der Funktion.

paramOptional

Der Name eines formalen Parameters für die Funktion. Für die Syntax der Parameter siehe dasFunktions-Referenz.

statementsOptional

Die Anweisungen, die den Körper der Funktion bilden. Derawait-Mechanismus kann verwendet werden.

Beschreibung

Eineasync function-Deklaration erstellt einAsyncFunction-Objekt. Jedes Mal, wenn eine asynchrone Funktion aufgerufen wird, gibt sie ein neuesPromise zurück, das mit dem Wert aufgelöst wird, der von der asynchronen Funktion zurückgegeben wird, oder mit einer Ausnahme abgelehnt wird, die innerhalb der asynchronen Funktion nicht abgefangen wird.

Asynchrone Funktionen können null oder mehrawait-Ausdrücke enthalten. Await-Ausdrücke lassen versprechensbasierte Funktionen so verhalten, als wären sie synchron, indem sie die Ausführung bis zur Erfüllung oder Ablehnung des zurückgegebenen Versprechens aussetzen. Der erfüllte Wert des Versprechens wird als Rückgabewert des Await-Ausdrucks behandelt. Der Gebrauch vonasync undawait ermöglicht die Verwendung gewöhnlichertry /catch-Blöcke um asynchronen Code.

Hinweis:Dasawait-Schlüsselwort ist nur innerhalb von asynchronen Funktionen in regulärem JavaScript-Code gültig. Wenn Sie es außerhalb des Körpers einer asynchronen Funktion verwenden, erhalten Sie einenSyntaxError.

await kann eigenständig mitJavaScript-Modulen verwendet werden.

Hinweis:Der Zweck vonasync/await ist die Vereinfachung der Syntaxdie zur Nutzung von Promise-basierten APIs notwendig ist. Das Verhaltenvonasync/await ist ähnlich wie die Kombination vonGeneratoren undPromises.

Asynchrone Funktionen geben immer ein Versprechen zurück. Wenn der Rückgabewert einer asynchronen Funktionnicht explizit ein Promise ist, wird es implizit in ein Promise gehüllt.

Betrachten Sie zum Beispiel folgenden Code:

js
async function foo() {  return 1;}

Er ist ähnlich wie:

js
function foo() {  return Promise.resolve(1);}

Beachten Sie, dass selbst wenn der Rückgabewert einer asynchronen Funktion so behandelt wird, als sei er inPromise.resolve gewickelt, sie nicht gleich sind. Eine asynchrone Funktion wird einen anderenVerweis zurückgeben, wohingegenPromise.resolve denselben Verweis zurückgibt, wenn der gegebene Wert ein Promise ist. Dies kann ein Problem sein, wenn Sie die Gleichheit eines Versprechens und eines Rückgabewerts einer asynchronen Funktion überprüfen möchten.

js
const p = new Promise((res, rej) => {  res(1);});async function asyncReturn() {  return p;}function basicReturn() {  return Promise.resolve(p);}console.log(p === basicReturn()); // trueconsole.log(p === asyncReturn()); // false

Der Körper einer asynchronen Funktion kann so betrachtet werden, dass er durch null oder mehr await-Ausdrücke aufgeteilt wird. Top-Level-Code, bis einschließlich des ersten Await-Ausdrucks (falls vorhanden), wird synchron ausgeführt. Auf diese Weise wird eine asynchrone Funktion ohne einen Await-Ausdruck synchron ausgeführt. Ist jedoch ein Await-Ausdruck im Funktionskörper vorhanden,wird die asynchrone Funktion immer asynchron abgeschlossen.

Zum Beispiel:

js
async function foo() {  await 1;}

Er ist ebenfalls gleichbedeutend mit:

js
function foo() {  return Promise.resolve(1).then(() => undefined);}

Code nach jedem Await-Ausdruck kann so betrachtet werden, als würde er in einem.thenRückruf existieren. Auf diese Weise wird eine Versprechenskette mit jedem Wiedereintrittin die Funktion progressiv aufgebaut. Der Rückgabewert bildet das letzte Glied in der Kette.

Im folgenden Beispiel warten wir nacheinander auf zwei Versprechen. Der Fortschritt bewegt sich durchdie Funktionfoo in drei Phasen.

  1. Die erste Zeile des Körpers der Funktionfoo wird synchron ausgeführt,mit dem Await-Ausdruck, der mit dem ausstehenden Versprechen konfiguriert ist. Der Fortschritt durchfoo wird dann ausgesetzt und die Kontrolle wird an die Funktion, diefoo aufgerufen hat, zurückgegeben.
  2. Einige Zeit später, wenn das erste Versprechen entweder erfüllt oder abgelehnt wurde,wird die Kontrolle zurück anfoo gegeben. Das Ergebnis der ersten Versprechens-Erfüllung(falls es nicht abgelehnt wurde) wird vom Await-Ausdruck zurückgegeben. Hier wird1result1 zugewiesen. Der Fortschritt geht weiter und der zweite Await-Ausdruckwird ausgewertet. Wieder wird der Fortschritt durchfoo unterbrochen und die Kontrolle wirdzurückgegeben.
  3. Einige Zeit später, wenn das zweite Versprechen entweder erfüllt oder abgelehnt wird,wird die Kontrolle erneut anfoo gegeben. Das Ergebnis der zweiten Versprechensauflösung wirdvom zweiten Await-Ausdruck zurückgegeben. Hier wird2result2 zugewiesen. Die Kontrolle geht zum Rückgabewert-Ausdruck (falls vorhanden). Der Standard-Rückgabewert vonundefined wird als der Auflösungswert desaktuellen Versprechens zurückgegeben.
js
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 Versprechenskettein Phasen konstruiert, da die Kontrolle nacheinander von der asynchronenFunktion abgegeben und dorthin zurückgegeben wird. Als Ergebnis müssen wir uns des Fehlerbehandlungsverhaltens bewusst sein, wenn wir mitgleichzeitigen asynchronen Operationen umgehen.

Zum Beispiel wird im folgenden Code ein unbehandelter Versprechensablehnungsfehler geworfen,selbst wenn ein.catch-Handler weiter entlang der Versprechenskettekonfiguriert wurde. Das liegt daran, dassp2 nicht in die Versprechenskette "eingebunden" wird, bisdie Kontrolle vonp1 zurückkommt.

js
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 wiefunction-Deklarationen — sie werdengehoisted an die Spitze ihres Gültigkeitsbereichs und können überall in ihrem Gültigkeitsbereich aufgerufen werden, und sie können nur in bestimmten Kontexten neu deklariert werden.

Beispiele

Asynchrone Funktionen und Ausführungsreihenfolge

js
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 finishsetTimeout(sequentialWait, 4000); // after 2 seconds, logs "slow" and then "fast"// wait againsetTimeout(concurrent1, 7000); // same as sequentialWait// wait againsetTimeout(concurrent2, 10000); // after 1 second, logs "fast", then after 1 more second, "slow"

await und Parallelität

InsequentialStart wird die Ausführung für 2 Sekunden für das ersteawait ausgesetzt und dann nochmal eine Sekunde für das zweiteawait. Derzweite Timer wird nicht erstellt, bis der erste bereits ausgelöst hat, sodass der Code nach 3 Sekunden beendet wird.

InsequentialWait werden beide Timer erstellt und dannawaited.Die Timer laufen gleichzeitig, was bedeutet, dass der Code nach 2 statt 3 Sekunden abgeschlossen wird,d.h. dem langsamsten Timer.Dieawait-Aufrufe laufen jedoch weiterhin in Serie, was bedeutet, dass der zweiteawait darauf wartet, dass der erste abgeschlossen wird. In diesem Fall wird das Ergebnis desschnellsten Timers nach dem langsamsten verarbeitet.

Wenn Sie sicher andere Aufgaben ausführen möchten, nachdem zwei oder mehr Aufgaben gleichzeitig ausgeführt wurden und abgeschlossen sind, müssen Sie einen Aufruf zuPromise.all() oderPromise.allSettled() erwarten, bevor die Aufgabe ausgeführt wird.

Warnung:Die FunktionensequentialWait undconcurrent1sind funktional nicht gleichwertig.

InsequentialWait, wenn das Versprechenfast zurückgewiesen wird, bevor das Versprechenslow erfüllt wird, wird ein unbehandelter Versprechensablehnungsfehlerausgelöst, unabhängig davon, ob der Aufrufer eine catch-Klausel konfiguriert hat.

Inconcurrent1 verdrahtetPromise.all die Versprechenskettein einem Durchgang, was bedeutet, dass der Vorgang schnell fehlschlägt, unabhängig von der Reihenfolge derZurückweisungen der Versprechen, und der Fehler tritt immer innerhalb der konfiguriertenVersprechenskette auf, sodass er auf normale Weise abgefangen werden kann.

Umschreiben einer Promise-Kette mit einer asynchronen Funktion

Ein API, das einPromise zurückgibt, wird zu einer Versprechenskette, und esteilt die Funktion in viele Teile. Betrachten Sie den folgenden Code:

js
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:

js
async function getProcessedData(url) {  let v;  try {    v = await downloadData(url);  } catch (e) {    v = await downloadFallbackData(url);  }  return processDataInWorker(v);}

Alternativ können Sie das Versprechen mitcatch() verketten:

js
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 demreturn-Schlüsselwort keineawait-Anweisung gibt, obwohl das auch gültig wäre: Der Rückgabewert einerasynchronen Funktion wird implizit inPromise.resolve gewickelt - wenner nicht bereits selbst ein Versprechen ist (wie in den Beispielen).

Spezifikationen

Specification
ECMAScript® 2026 Language Specification
# sec-async-function-definitions

Browser-Kompatibilität

Siehe auch

MDN-Feedback-Box

Diese Seite wurde automatisch aus dem Englischen übersetzt.


[8]ページ先頭

©2009-2025 Movatter.jp