Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

An asynchronous generator function is a special type of function declared with async function* that combines the pausing execution context of a generator with the asynchronous resolution of an async function. When invoked, it does not execute its body immediately; instead, it returns an AsyncGenerator object, which implements both the Async Iterator and Async Iterable protocols.

Syntax

async function* asyncGeneratorName([param[, param[, ...param]]]) {
  statements
}

Core Mechanics

An async generator function allows the use of both await and yield keywords within its body.
  1. await: Pauses the internal execution of the generator until a given Promise settles.
  2. yield: Pauses the generator and emits a value. If a Promise is passed to yield, the async generator implicitly awaits it before emitting the resolved value. It never yields a Promise directly to the consumer.
Unlike synchronous generators where calling .next() returns a raw IteratorResult object ({ value, done }), calling .next() on an AsyncGenerator returns a Promise that resolves to an IteratorResult object.

Execution and Consumption

Because the AsyncGenerator’s .next() method returns a Promise, it must be consumed asynchronously. This is typically done using the for await...of statement or by manually resolving the Promises returned by .next().

Manual Iteration

async function* asyncCounter() {
  await new Promise(resolve => setTimeout(resolve, 100)); // Internal async pause
  yield 1;
  yield 2;
}

const iterator = asyncCounter();

// .next() returns a Promise resolving to an IteratorResult
iterator.next().then(result => console.log(result)); // { value: 1, done: false }
iterator.next().then(result => console.log(result)); // { value: 2, done: false }
iterator.next().then(result => console.log(result)); // { value: undefined, done: true }

Protocol Iteration (for await...of)

The for await...of statement automatically handles the resolution of the Promises returned by the AsyncGenerator’s .next() method, extracting the value and terminating when done: true is reached.
async function consumeAsyncGenerator() {
  const iterator = asyncCounter();
  
  for await (const value of iterator) {
    console.log(value); // Logs 1, then 2
  }
}

Delegation with yield*

The yield* expression in an async generator delegates execution to another iterable. In an async function*, yield* can delegate to both Async Iterables (like other async generators) and Synchronous Iterables (like Arrays or Sets).
async function* subGenerator() {
  yield 'b';
}

async function* mainGenerator() {
  yield 'a';
  yield* subGenerator(); // Delegates to an Async Iterable
  yield* ['c', 'd'];     // Delegates to a Sync Iterable
}

// Consumption will yield: 'a', 'b', 'c', 'd'

Error Handling and Control Flow

The AsyncGenerator object provides .throw() and .return() methods, which also return Promises.
  • iterator.throw(error): Injects an exception into the generator at the current suspended yield expression. If the generator has a try...catch block around the yield, it can catch the error and continue. If the injected error is uncaught, the Promise returned by the .throw() method itself rejects, and the generator is permanently closed. Any subsequent calls to .next() will simply return a Promise that resolves to { value: undefined, done: true }.
  • iterator.return(value): Prematurely terminates the generator. It returns a Promise that resolves to { value: providedValue, done: true } and triggers the execution of any pending finally blocks inside the generator.
async function* errorHandlingGenerator() {
  try {
    yield 1;
    yield 2;
  } catch (err) {
    yield `Caught: ${err.message}`;
  }
}

const gen = errorHandlingGenerator();
gen.next().then(console.log); // { value: 1, done: false }

// Injects an error, which is caught internally
gen.throw(new Error("Halt")).then(console.log); // { value: 'Caught: Halt', done: false }

// Generator is now closed because it exited the try/catch block
gen.next().then(console.log); // { value: undefined, done: true }
Master JavaScript with Deep Grasping Methodology!Learn More