for await...of
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.
Die for await...of
-Anweisung erstellt eine Schleife, die über asynchrone iterierbare Objekte sowie synchrone Iterables iteriert. Diese Anweisung kann nur in Kontexten verwendet werden, in denen await
zulässig ist, einschließlich innerhalb des Körpers einer async function oder in einem Modul.
Probieren Sie es aus
async function* foo() {
yield 1;
yield 2;
}
(async function () {
for await (const num of foo()) {
console.log(num);
// Expected output: 1
break; // Closes iterator, triggers return
}
})();
Syntax
for await (variable of iterable)
statement
variable
-
Erhält bei jeder Iteration einen Wert aus der Sequenz. Kann entweder eine Deklaration mit
const
,let
odervar
sein oder ein Zuweisungsziel (z. B. eine zuvor deklarierte Variable, eine Objekteigenschaft oder ein Destrukturierungsmuster). Variablen, die mitvar
deklariert wurden, sind nicht lokal für die Schleife, d.h., sie befinden sich im selben Gültigkeitsbereich wie diefor await...of
-Schleife. iterable
-
Ein asynchrones oder synchrones Iterable. Die Quelle der Sequenz von Werten, über die die Schleife arbeitet.
statement
-
Eine Anweisung, die bei jeder Iteration ausgeführt wird. Kann
variable
referenzieren. Sie können eine Block-Anweisung verwenden, um mehrere Anweisungen auszuführen.
Beschreibung
Wenn eine for await...of
-Schleife über ein Iterable iteriert, ruft sie zuerst die Methode [Symbol.asyncIterator]()
des Iterables auf, was einen asynchronen Iterator zurückgibt. Falls die @asyncIterator
-Methode nicht existiert, sucht sie nach einer [Symbol.iterator]()
-Methode, die einen synchronen Iterator zurückgibt. Der zurückgegebene synchrone Iterator wird dann in einen asynchronen Iterator umgewandelt, indem jedes Objekt, das von den Methoden next()
, return()
und throw()
zurückgegeben wird, in ein aufgelöstes oder abgelehntes Promise gewrappt wird, wobei die value
-Eigenschaft aufgelöst wird, falls auch sie ein Promise ist. Die Schleife ruft dann wiederholt die Methode next()
des endgültigen asynchronen Iterators auf und awaitet das zurückgegebene Promise, um die Sequenz von Werten zu erzeugen, die der variable
zugewiesen werden.
Eine for await...of
-Schleife endet, wenn der Iterator abgeschlossen ist (das awaitete Ergebnis von next()
ist ein Objekt mit done: true
). Wie bei anderen Schleifen-Anweisungen können innerhalb von statement
Steuerfluss-Anweisungen verwendet werden:
break
beendet die Ausführung vonstatement
und springt zur ersten Anweisung nach der Schleife.continue
beendet die Ausführung vonstatement
und springt zur nächsten Iteration der Schleife.
Falls die for await...of
-Schleife vorzeitig beendet wird (z. B. durch eine break
-Anweisung oder einen geworfenen Fehler), wird die Methode return()
des Iterators aufgerufen, um Bereinigungsoperationen durchzuführen. Das zurückgegebene Promise wird awaitet, bevor die Schleife endet.
for await...of
funktioniert im Allgemeinen genauso wie die for...of
-Schleife und teilt viele der gleichen Syntax- und Semantikregeln. Es gibt jedoch einige Unterschiede:
for await...of
funktioniert sowohl für synchrone als auch für asynchrone Iterables, währendfor...of
nur für synchrone Iterables funktioniert.for await...of
kann nur in Kontexten verwendet werden, in denenawait
zulässig ist, z. B. innerhalb einer async function oder eines Moduls. Auch wenn das Iterable synchron ist, wartet die Schleife den Rückgabewert jeder Iteration ab, was zu einer langsameren Ausführung durch wiederholtes Entpacken von Promises führt.- Wenn das
iterable
ein synchrones Iterable ist, das Promises liefert, würdefor await...of
eine Sequenz von aufgelösten Werten erzeugen, währendfor...of
eine Sequenz von Promises erzeugen würde. (Beachten Sie jedoch Fehlerbehandlung und Bereinigung – siehe Iterieren über synchrone Iterables und Generatoren) - Bei
for await...of
kannvariable
der Bezeichnerasync
sein (z. B.for await (async of foo)
); beifor...of
ist dieser Fall nicht erlaubt.
Beispiele
Iterieren über asynchrone Iterables
Sie können auch über ein Objekt iterieren, das explizit das asynchrone Iterable-Protokoll implementiert:
const LIMIT = 3;
const asyncIterable = {
[Symbol.asyncIterator]() {
let i = 0;
return {
next() {
const done = i === LIMIT;
const value = done ? undefined : i++;
return Promise.resolve({ value, done });
},
return() {
// This will be reached if the consumer called 'break' or 'return' early in the loop.
return { done: true };
},
};
},
};
(async () => {
for await (const num of asyncIterable) {
console.log(num);
}
})();
// 0
// 1
// 2
Iterieren über asynchrone Generatoren
Da die Rückgabewerte asynchroner Generatorfunktionen mit dem asynchronen Iterable-Protokoll übereinstimmen, können diese mit for await...of
durchlaufen werden.
async function* asyncGenerator() {
let i = 0;
while (i < 3) {
yield i++;
}
}
(async () => {
for await (const num of asyncGenerator()) {
console.log(num);
}
})();
// 0
// 1
// 2
Ein konkreteres Beispiel für das Iterieren über einen asynchronen Generator mit for await...of
ist das Durchlaufen von Daten aus einer API.
In diesem Beispiel wird zunächst ein asynchrones Iterable für einen Datenstrom erstellt und anschließend verwendet, um die Größe der Antwort von der API zu ermitteln.
async function* streamAsyncIterable(stream) {
const reader = stream.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (done) return;
yield value;
}
} finally {
reader.releaseLock();
}
}
// Fetches data from URL and calculates response size using the async generator.
async function getResponseSize(url) {
const response = await fetch(url);
// Will hold the size of the response, in bytes.
let responseSize = 0;
// The for-await-of loop. Async iterates over each portion of the response.
for await (const chunk of streamAsyncIterable(response.body)) {
// Incrementing the total response length.
responseSize += chunk.length;
}
console.log(`Response Size: ${responseSize} bytes`); // "Response Size: 1071472"
return responseSize;
}
getResponseSize("https://jsonplaceholder.typicode.com/photos");
Iterieren über synchrone Iterables und Generatoren
Die for await...of
-Schleife verarbeitet auch synchrone Iterables und Generatoren. In solchen Fällen wartet sie intern auf die ausgegebenen Werte, bevor sie diese der Schleifensteuerungsvariablen zuweist.
function* generator() {
yield 0;
yield 1;
yield Promise.resolve(2);
yield Promise.resolve(3);
yield 4;
}
(async () => {
for await (const num of generator()) {
console.log(num);
}
})();
// 0
// 1
// 2
// 3
// 4
// compare with for-of loop:
for (const numOrPromise of generator()) {
console.log(numOrPromise);
}
// 0
// 1
// Promise { 2 }
// Promise { 3 }
// 4
Hinweis:
Seien Sie vorsichtig bei der Ausgabe abgelehnter Promises aus einem synchronen Generator. In solchen Fällen wirft for await...of
beim Verarbeiten des abgelehnten Promises einen Fehler und RUFT NICHT die finally
-Blöcke innerhalb dieses Generators auf. Dies kann unerwünscht sein, wenn Sie einige zugewiesene Ressourcen mit try/finally
freigeben müssen.
function* generatorWithRejectedPromises() {
try {
yield 0;
yield 1;
yield Promise.resolve(2);
yield Promise.reject(3);
yield 4;
throw 5;
} finally {
console.log("called finally");
}
}
(async () => {
try {
for await (const num of generatorWithRejectedPromises()) {
console.log(num);
}
} catch (e) {
console.log("caught", e);
}
})();
// 0
// 1
// 2
// caught 3
// compare with for-of loop:
try {
for (const numOrPromise of generatorWithRejectedPromises()) {
console.log(numOrPromise);
}
} catch (e) {
console.log("caught", e);
}
// 0
// 1
// Promise { 2 }
// Promise { <rejected> 3 }
// 4
// caught 5
// called finally
Um sicherzustellen, dass die finally
-Blöcke eines synchronen Generators immer aufgerufen werden, verwenden Sie die geeignete Form der Schleife — for await...of
für den asynchronen Generator und for...of
für den synchronen — und warten Sie im Schleifen-Block explizit auf die ausgegebenen Promises.
(async () => {
try {
for (const numOrPromise of generatorWithRejectedPromises()) {
console.log(await numOrPromise);
}
} catch (e) {
console.log("caught", e);
}
})();
// 0
// 1
// 2
// caught 3
// called finally
Spezifikationen
Specification |
---|
ECMAScript® 2025 Language Specification # sec-for-in-and-for-of-statements |
Browser-Kompatibilität
Report problems with this compatibility data on GitHubdesktop | mobile | server | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
for await...of |
Legend
Tip: you can click/tap on a cell for more information.
- Full support
- Full support