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 method is a function defined within an object literal or a class that combines the async and * (generator) modifiers. It allows the sequential yielding of asynchronously resolved values, returning an AsyncGenerator object that conforms to both the AsyncIterator and AsyncIterable protocols.

Syntax

The method is declared by prefixing the method name with an asterisk * and preceding the entire declaration with the async keyword.
// Inside an Object Literal
const obj = {
  async *asyncGenMethod() {
    yield await Promise.resolve(1);
  }
};

// Inside a Class
class DataHandler {
  async *asyncGenMethod() {
    yield await Promise.resolve(2);
  }
  
  // Static async generator method
  static async *staticAsyncGenMethod() {
    yield await Promise.resolve(3);
  }
}

Core Mechanics

  1. Execution Suspension: Like synchronous generators, execution pauses at yield expressions. Like standard async functions, execution also pauses at await expressions.
  2. Return Type: Invoking the method does not execute its body immediately. Instead, it returns an AsyncGenerator instance.
  3. Iterator Result: Calling .next() on the returned AsyncGenerator returns a Promise that resolves to an IteratorResult object: { value: any, done: boolean }. This contrasts with synchronous generators, which return the IteratorResult directly.

Mechanical Example

The following demonstrates the internal state progression when manually invoking .next() on an async generator method.
class Sequence {
  async *generate() {
    const a = await Promise.resolve("first");
    yield a;
    
    const b = await Promise.resolve("second");
    yield b;
    
    return "complete";
  }
}

const seq = new Sequence();
const iterator = seq.generate();

// Each .next() call returns a Promise
iterator.next().then(result => console.log(result)); 
// Output: { value: 'first', done: false }

iterator.next().then(result => console.log(result)); 
// Output: { value: 'second', done: false }

iterator.next().then(result => console.log(result)); 
// Output: { value: 'complete', done: true }

Protocol Consumption

Because the method returns an object implementing the AsyncIterable protocol (via the Symbol.asyncIterator well-known symbol), it is natively consumed by the for await...of statement. The loop automatically awaits each yielded Promise and terminates when done: true is reached.
const collection = {
  async *[Symbol.asyncIterator]() {
    yield 10;
    yield 20;
  }
};

(async () => {
  for await (const value of collection) {
    console.log(value); // Logs 10, then 20
  }
})();

Delegation (yield*)

Inside an async generator method, the yield* expression delegates execution to another iterable. In an asynchronous context, yield* can delegate to both AsyncIterable objects (like other async generators) and standard synchronous Iterable objects (like Arrays or standard generators).
class Delegator {
  async *subRoutine() {
    yield await Promise.resolve('A');
    yield await Promise.resolve('B');
  }

  async *mainRoutine() {
    yield 'Start';
    yield* this.subRoutine(); // Delegates to another AsyncGenerator
    yield* [1, 2];            // Delegates to a synchronous Iterable
    yield 'End';
  }
}
Master JavaScript with Deep Grasping Methodology!Learn More