for await...of and Async Generators
Iterates an async iterable — one whose Symbol.asyncIterator produces promises — the async counterpart to for...of.
for await (const value of asyncIterable) {} / async function* gen() { yield value; }
Purpose
for await...of iterates an async iterable — one implementing Symbol.asyncIterator, whose
.next() produces promises instead of plain values — awaiting each one automatically. An async
generator (async function*) is the easiest way to produce one.
Syntax
async function* fetchPages(baseUrl) {
let page = 1;
while (true) {
const response = await fetch(`${baseUrl}?page=${page}`);
const data = await response.json();
if (data.items.length === 0) return;
yield data.items;
page++;
}
}
for await (const items of fetchPages('/api/results')) {
console.log(`Got ${items.length} items`);
}
Behavior notes
for await...ofcan be used inside anasyncfunction on any async iterable — or even on a regular (non-async) iterable of promises, awaiting each one in turn.- An async generator combines
async/awaitandyieldfreely inside the same function body, awaiting intermediate results before yielding a value onward. - This is the foundation streaming APIs build on — a
ReadableStream’s reader, or a paginated fetch helper, process chunks of data as they arrive instead of buffering an entire response first.
Common mistakes
- Using a plain
for...ofon an async iterable — it won’t await the produced promises, yielding unresolvedPromiseobjects instead of their values. - Assuming an async generator fetches all pages eagerly — like a regular generator, it only advances
as far as something has actually requested, one
yieldat a time.
Runtime notes
Core ECMAScript (ES2018), identical behavior across every current browser and Node version.