Skip to main content
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

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

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.

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).

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.
Tired of Poor JavaScript Skills? Fix That With Deep Grasping!Learn More