[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/async_function [Back]  [Original]

async function - JavaScript | MDN

Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.

View in English Always switch to English

async function

Baseline Weitgehend verfgbar

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.

In diesem Artikel

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 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.

Parameter

name

Der Name der Funktion.

param Optional

Der Name eines formalen Parameters fr die Funktion. Fr die Syntax der Parameter siehe das Funktions-Referenz.

statements Optional

Die Anweisungen, die den Krper der Funktion bilden. Der await-Mechanismus kann verwendet werden.

Beschreibung

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:

js
async function foo() {
  return 1;
}

Er ist hnlich wie:

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

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

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 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.

  1. Die erste Zeile des Krpers der Funktion 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.
  2. Einige Zeit spter, wenn das erste Versprechen entweder erfllt oder abgelehnt wurde, wird die Kontrolle zurck an 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.
  3. Einige Zeit spter, wenn das zweite Versprechen entweder erfllt oder abgelehnt wird, wird die Kontrolle erneut an 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.
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 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.

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 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.

Beispiele

Asynchrone Funktionen und Ausfhrungsreihenfolge

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 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"

await und Parallelitt

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.

Umschreiben einer Promise-Kette mit einer asynchronen Funktion

Ein API, das ein Promise zurckgibt, wird zu einer Versprechenskette, und es teilt 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 knnen Sie das Versprechen mit catch() 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 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).

Spezifikationen

Spezifikation
ECMAScript 2027 LanguageSpecification
# sec-async-function-definitions

Browser-Kompatibilitt

Siehe auch


Web Proxy Viewer  |  New URL  |  Original Page