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.

A generator function is a specialized function in JavaScript that can pause its execution context and resume it at a later time. Unlike standard functions that run to completion (run-to-completion semantics) and return a single value, generator functions yield multiple values sequentially on demand, maintaining their internal state, local variables, and lexical bindings across pauses. When invoked, a generator function does not execute its body immediately. Instead, it returns a Generator object, which conforms to both the Iterable and Iterator protocols.

Syntax

A generator function is defined using the function* declaration (or expression) and utilizes the yield keyword to pause execution.
function* identifier() {
  yield expression;
}

Execution Mechanics

Execution of the generator’s body is controlled by the next() method of the returned Generator object.
  1. Calling .next() starts or resumes execution until it encounters a yield expression.
  2. The generator pauses, and .next() returns an IteratorResult object with two properties:
    • value: The evaluated expression following the yield keyword.
    • done: A boolean indicating whether the generator has completed execution (true if a return statement is reached or the end of the function is hit).
function* stateMachine() {
  yield 'state 1';
  yield 'state 2';
  return 'terminal state';
}

const machine = stateMachine(); // Execution is paused at the top of the function

console.log(machine.next()); // { value: 'state 1', done: false }
console.log(machine.next()); // { value: 'state 2', done: false }
console.log(machine.next()); // { value: 'terminal state', done: true }
console.log(machine.next()); // { value: undefined, done: true }

Two-Way Communication

The yield keyword is an expression that evaluates to a value. By passing an argument to the .next() method, the caller can inject data back into the generator’s execution context. The injected value becomes the evaluated result of the currently paused yield expression. Note: An argument passed to the very first .next() call is ignored, as there is no previously paused yield expression to receive it.
function* bidirectional() {
  const firstInput = yield 'ready';
  const secondInput = yield firstInput * 2;
  return secondInput;
}

const gen = bidirectional();

console.log(gen.next());      // { value: 'ready', done: false } (Pauses at first yield)
console.log(gen.next(10));    // { value: 20, done: false }      (firstInput = 10, yields 20)
console.log(gen.next('end')); // { value: 'end', done: true }    (secondInput = 'end', returns 'end')

Generator Delegation (yield*)

The yield* expression delegates execution to another generator or iterable object. The outer generator pauses and yields all values from the delegated iterable until it is exhausted, at which point the outer generator resumes.
function* subGenerator() {
  yield 'b';
  yield 'c';
}

function* mainGenerator() {
  yield 'a';
  yield* subGenerator(); // Delegates to subGenerator
  yield 'd';
}

const main = mainGenerator();
// Successive .next() calls will yield: 'a', 'b', 'c', 'd'

Lifecycle Control Methods

In addition to .next(), the Generator object exposes two methods to forcefully alter the generator’s lifecycle from the outside:
  • Generator.prototype.return(value): Prematurely terminates the generator. It acts as if a return value; statement was executed at the current suspended yield point.
  • Generator.prototype.throw(exception): Injects an exception into the generator at the suspended yield point. If the generator has a try...catch block surrounding the yield, it can catch the exception and continue; otherwise, the exception propagates out, and the generator terminates.
Master JavaScript with Deep Grasping Methodology!Learn More