Async generators combine two separate JavaScript features — generators (yield) and async/await — letting you lazily produce a sequence of values that each require an asynchronous operation to obtain.
async function* fetchPages(baseUrl) {
let page = 1;
while (true) {
const res = await fetch(<code>${baseUrl}?page=${page}</code>);
const data = await res.json();
if (data.items.length === 0) return; // no more pages
yield data.items;
page++;
}
}
// Consume with for-await-of
async function processAllItems() {
for await (const items of fetchPages('/api/products')) {
console.log(<code>Got ${items.length} items</code>);
}
}
This pattern is genuinely useful for paginated APIs — the caller doesn’t need to know or care about page numbers at all, it just consumes items until the generator naturally stops, and each page is only fetched when actually needed rather than all upfront.