Node.js › Async Patterns

What is an async generator, and how does 'for await...of' let you consume asynchronously produced data?

Advanced

Answer

An async generator (declared with 'async function*') can yield values over time, each potentially resolved from an awaited asynchronous operation, producing an async iterator that a consumer walks through using 'for await...of' -- this is especially useful for processing paginated API results, streaming database cursors, or any data source that arrives incrementally rather than all at once, without needing to load the entire dataset into memory first.
async function* fetchAllPages(url) {
  let nextUrl = url;
  while (nextUrl) {
    const response = await fetch(nextUrl);
    const page = await response.json();
    yield page.items;
    nextUrl = page.nextPageUrl;
  }
}

for await (const items of fetchAllPages('/api/users')) {
  console.log(`Got a page of ${items.length} users`);
}
Real-world example A data-export job consuming a paginated third-party API uses an async generator to yield each page of results as it arrives, processing and writing each batch to disk immediately rather than accumulating potentially hundreds of thousands of records in memory before starting to write anything.

Common follow-ups: How do async generators relate to Node.js readable streams, given both represent asynchronous sequences of data?;What happens if the consuming 'for await...of' loop is exited early with a break -- does the generator clean up properly?