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 class or object literal member prefixed with both async and *. It combines the pause-and-resume execution model of generators with the non-blocking, promise-based resolution of asynchronous functions. When invoked, it does not execute its body immediately; instead, it returns an AsyncGenerator object. The generator yields values of type TYield, and it is the .next() method of the resulting iterator that returns a Promise<IteratorResult<TYield>>.

TypeScript Signatures and Typing

In TypeScript, the return type of an async generator method is strictly typed using the built-in AsyncGenerator<TYield, TReturn, TNext> interface:
  • TYield: The type of the values yielded by the method.
  • TReturn: The type of the value returned when the generator completes (defaults to void or any).
  • TNext: The type of the value accepted by the next() method (defaults to unknown).
Alternatively, you can type the return signature using AsyncIterable<TYield> or AsyncIterableIterator<TYield> if you do not need to strictly type the return or next values.
class StreamHandler {
    // Explicitly typing Yield, Return, and Next types
    public async *extractData(): AsyncGenerator<Uint8Array, number, string> {
        // 'command' is typed as 'string' based on TNext
        const command: string = yield new Uint8Array([1, 2, 3]);
        
        if (command === "STOP") {
            return 0; // Typed as 'number' based on TReturn
        }
        
        yield new Uint8Array([4, 5, 6]);
        return 1;
    }
}

// Object literal syntax
const asyncIterableObj = {
    async *generateSequence(): AsyncIterableIterator<number> {
        yield await Promise.resolve(10);
        yield await Promise.resolve(20);
    }
};

Execution Mechanics

  1. Initialization: Calling the method instantiates the AsyncGenerator. No code inside the method executes until .next() is called.
  2. Promise Resolution: Every yield expression pauses execution. The yielded value is automatically wrapped in a Promise if it is not already one.
  3. IteratorResult: The .next() method returns a Promise that resolves to an IteratorResult object containing two properties:
    • value: The yielded or returned value.
    • done: A boolean indicating whether the generator has completed (true on return, false on yield).
const handler = new StreamHandler();
const generator = handler.extractData();

// Manual iteration mechanics
generator.next().then(result => {
    console.log(result); // { value: Uint8Array(3) [1, 2, 3], done: false }
    
    // Passing TNext back into the generator
    return generator.next("STOP"); 
}).then(result => {
    console.log(result); // { value: 0, done: true }
});

Delegation with yield*

An async generator method can delegate its execution to another AsyncIterable, Iterable, or generator using the yield* expression. TypeScript enforces that the delegated iterable’s yield type is compatible with the parent method’s TYield type.
class CompositeGenerator {
    private async *subRoutine(): AsyncGenerator<string, void, unknown> {
        yield "sub-yield-1";
        yield "sub-yield-2";
    }

    public async *mainRoutine(): AsyncGenerator<string, void, unknown> {
        yield "main-yield-1";
        // Delegates iteration to subRoutine
        yield* this.subRoutine(); 
        yield "main-yield-2";
    }
}

Consumption via for await...of

While manual .next() calls expose the underlying Promise mechanics, async generator methods are natively designed to be consumed by the for await...of statement. This construct implicitly awaits each Promise and extracts the value from the IteratorResult, automatically terminating when done: true is encountered.
async function consume(handler: CompositeGenerator) {
    // TypeScript infers 'item' as 'string' based on TYield
    for await (const item of handler.mainRoutine()) {
        console.log(item);
    }
}
Master TypeScript with Deep Grasping Methodology!Learn More