← Back to TypeScript Course | Chapter 21: Symbols and Iterators | Lesson 5 of 6

Async Generators

Async generators combine generators with asynchronous operations. They use async function* and produce values through the AsyncIterator protocol, which can be consumed with for await...of.

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

typescript
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

typescript
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

typescript
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

typescript
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

typescript
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();
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.