Consume asynchronous data
Values are produced with delays or on demand.
JS Puzzles · Const
for await...of processes values from an async iterable as they become available. It is the asynchronous counterpart of for...of and is commonly paired with async generators.
for await...of consumes an asynchronous iterable one item at a time. Each iteration waits for the iterator's promise, assigns the resulting value to the loop variable, and stops when the iterator reports completion.
for await (const variable of iterable) { ... }| Name | Type | Description |
|---|---|---|
variable | binding or assignment target | A binding or assignment target receiving each produced value. |
iterable | async iterable or sync iterable | An async iterable, or a synchronous iterable adapted for asynchronous iteration. |
No value; the loop executes its body for each item and completes when iteration ends.
Symbol.asyncIterator, whose iterator's next() method returns a promise.next() produces a promise for the next iterator result.await between for and the parenthesized binding-and-source clause.let, const, or var; an assignment target may also be used, but it cannot be a declaration without a binding.await is permitted, such as inside an async function or a module.for...of instead of for await...of does not await asynchronous iterator results.async function* numbers() {
yield 1;
await new Promise(resolve => setTimeout(resolve, 10));
yield 2;
}
async function main() {
for await (const number of numbers()) {
console.log(number);
}
}
main();An async generator produces values over time, and the loop awaits each value before continuing.
Values are produced with delays or on demand.
An async generator emits a sequence over time.
A data source arrives in chunks, such as network output.
for await...of choose an iterator?It first uses the object's Symbol.asyncIterator method. If that is unavailable, it falls back to Symbol.iterator, wrapping the synchronous iterator so its results can be awaited.
Follow-up: What happens to a promise yielded by an async generator? The loop awaits it and exposes its fulfilled value to the loop body.
The iterator's next() method returns a promise for an iterator result. Each result is awaited, its value is assigned to the loop variable, and iteration ends when done is true.
Follow-up: Why can ordinary arrays be used? Synchronous iterables are adapted automatically when no async iterator exists.
It can be used only in an async function or another context where await is valid, including a module. This restriction exists because each iteration waits asynchronously.
Follow-up: Can a synchronous iterable be used there? Yes; the loop wraps its iterator and still awaits each produced result.
async iteratorsasync generatorsSymbol.asyncIteratorSymbol.iteratorfor...of