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.

The yield keyword is an operator used exclusively within generator functions (function*) and asynchronous generator functions (async function*) to pause the execution context and yield a value to the caller. It acts as a bidirectional control-flow mechanism, allowing a generator to emit a sequence of values over time and receive injected values or exceptions when execution is resumed.

Syntax

[rv] = yield [expression];
  • expression: The value to be evaluated and yielded to the caller via the iterator protocol. If omitted, the generator yields undefined.
  • rv: The value the yield expression evaluates to inside the generator. This is determined by the argument passed back into the generator when the caller invokes the generator’s next() method.

Execution Mechanics

When the JavaScript engine evaluates a yield expression, the following sequence occurs:
  1. Evaluation: The expression following the yield keyword is evaluated.
  2. Suspension: The generator’s execution context (local variables, lexical scope, and instruction pointer) is frozen in memory.
  3. Emission: The evaluated expression is wrapped in an IteratorResult object shaped as { value: <expression_result>, done: false }. For synchronous generators, this object is yielded directly to the caller. For asynchronous generators, the caller receives a Promise that resolves to this IteratorResult object.
  4. Resumption: The generator remains suspended until the caller invokes one of the iterator’s control methods: next(), throw(), or return().
  5. Injection/Termination:
    • If next(val) is invoked, val becomes the evaluated result of the entire yield expression in the resumed execution context.
    • If throw(err) is invoked, the generator resumes by throwing the err exception directly at the location of the suspended yield expression.
    • If return(val) is invoked, the generator immediately terminates, executing any pending finally blocks, and returns { value: val, done: true }.
function* statefulGenerator() {
    // Pauses execution, yields { value: 10, done: false }
    // The variable 'injected' remains unassigned until next() is called again.
    const injected = yield 10; 
    
    // Resumes execution, evaluates (injected * 2), yields result
    yield injected * 2; 
}

const iterator = statefulGenerator();

iterator.next();   // Yields { value: 10, done: false }
iterator.next(7);  // Injects 7 into 'injected', yields { value: 14, done: false }
iterator.next();   // Returns { value: undefined, done: true }

Operator Precedence

yield is a right-associative operator with very low precedence (equivalent to assignment operators). Because of this low precedence, an expression like yield 1 + 2 is perfectly valid and evaluates as yield (1 + 2). However, when a yield expression is used as an operand for an operator with higher precedence, the yield expression must be wrapped in parentheses. Failing to do so results in a SyntaxError. For example, the grammar rules for the addition operator (+) require a higher-precedence expression (a MultiplicativeExpression) on its right side. Because yield 2 is an AssignmentExpression (lower precedence), the parser fails to match the grammar and throws an error.
function* precedenceGenerator() {
    // Valid: Evaluates as `yield (1 + 2)`. Yields 3.
    const a = yield 1 + 2; 
    
    // SyntaxError: The + operator expects a higher-precedence expression on its right.
    // const b = 1 + yield 2; 
    
    // Correct: Parentheses isolate the yield expression, satisfying the grammar.
    // Yields 2, then assigns (1 + <injected_value>) to c.
    const c = 1 + (yield 2); 
}

Yield Delegation (yield*)

The yield* expression is a specialized variant that delegates iteration control to another iterable object (such as another generator, an Array, a Map, or a String). Instead of yielding the iterable object itself, yield* iterates over the target and yields each of its values sequentially. The yield* expression itself evaluates to the return value of the delegated iterator (the value when done: true).
function* innerGenerator() {
    yield 'A';
    return 'Inner Complete';
}

function* outerGenerator() {
    yield 1;
    // Delegates to innerGenerator. 
    // Yields 'A', then assigns the return value to 'result'
    const result = yield* innerGenerator(); 
    yield result;
}

const iter = outerGenerator();
iter.next(); // { value: 1, done: false }
iter.next(); // { value: 'A', done: false }
iter.next(); // { value: 'Inner Complete', done: false }
iter.next(); // { value: undefined, done: true }
Master JavaScript with Deep Grasping Methodology!Learn More