Async Generators
In this page:
async function* name(): AsyncGenerator<YieldType> {
yield value;
}
for await (const item of name()) {
// use item
}
Basic Async Generator
An async generator can await asynchronous work in between each yield, and its return type can be fully described as AsyncGenerator<YieldType, ReturnType, NextType> for all three value slots.
Example: Basic Async Generator
async function* countAsync(): AsyncGenerator<number, void, unknown> {
yield 1;
yield 2;
}
async function run() {
for await (const n of countAsync()) console.log(n);
}
run();
Async Data Sequences
Async generators fit naturally whenever each item in a sequence requires its own asynchronous step — fetching one page of results at a time, or waiting on a remote data source before producing the next value.
Example: Async Data Sequences
async function* fetchPages(): AsyncGenerator<string> {
yield "page 1";
yield "page 2";
}
async function run() {
for await (const page of fetchPages()) console.log(page);
}
run();
Async Generator Return Types
AsyncGenerator's type parameters let you specify exactly what type gets yielded, what type the generator ultimately returns, and what type of value can be passed back in through next — the same three-part contract as a regular generator, just asynchronous.
Example: Async Generator Return Types
async function* gen(): AsyncGenerator<number, string, unknown> {
yield 1;
return "complete";
}
async function run() {
const it = gen();
console.log(await it.next());
console.log(await it.next());
}
run();
for await...of
The for await...of loop is built specifically to consume async iterators — it automatically awaits each step's result, which is what lets it work naturally with both async generators and other async iterables.
Example: for await...of
async function* asyncNums(): AsyncGenerator<number> {
yield 10;
yield 20;
}
async function run() {
for await (const n of asyncNums()) {
console.log(n);
}
}
run();
Async Generator Pipelines
Async generators can be chained together to build a lazy processing pipeline, where each stage only pulls and processes the next value once the stage after it actually asks for it.
Example: Async Generator Pipelines
async function* numbers(): AsyncGenerator<number> {
yield 1;
yield 2;
yield 3;
}
async function* doubled(source: AsyncGenerator<number>): AsyncGenerator<number> {
for await (const n of source) yield n * 2;
}
async function run() {
for await (const n of doubled(numbers())) console.log(n);
}
run();
- Using a normal
for...ofon an async generator, when it requiresfor await...of. - Writing
async function*but typing it asGeneratorinstead ofAsyncGenerator. - Using
for awaitoutside anasyncfunction (or top-level module), which is an error.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: