Useful Cheatsheetsusefulcheatsheets.com
JavaScript Generators
Chapter 30 · Page 237
Advanced

JavaScript Generators

Learn how generator functions pause and resume execution to build lazy sequences and iterables.

TL;DR

  1. 01Declare generators with function* to suspend and resume functions.
  2. 02Emit values lazily on demand using the yield keyword.
  3. 03Forward iteration sequences to external collections using yield* delegation.

Tips

  1. 01Use generators to compute massive data sequences lazily without consuming system memory up front.
  2. 02Assign generator methods to Symbol.iterator properties to create custom iterables cleanly.

Warnings

  1. 01Catch exceptions thrown inside generator scopes to prevent them from closing the iterator permanently.
  2. 02Avoid using spread syntax on infinite generators to prevent crashing the browser thread.
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Generators
Chapter 30 · Page 238
Advanced

JavaScript Generators

(continued)

Generator Basics

  • function* declaration

    Declares generators which return an iterator object instead of running code.

    function* counter() {
      yield 1;
      yield 2;
    }
    const it = counter();
  • next() calls

    Resumes execution block internally until encountering the next yield line.

    it.next(); // { value: 1, done: false }
    it.next(); // { value: 2, done: false }
  • Return values

    Signals completion with done true and returns standard values if declared.

    function* range() {
      yield 1;
      return "stop";
    }
    const it2 = range();
    it2.next(); // { value: 1, done: false }
    it2.next(); // { value: "stop", done: true }
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Generators
Chapter 30 · Page 239
Advanced

JavaScript Generators

(continued)

Controlling Generators

  • Value injection

    Passes parameter values back into the generator at pause lines.

    function* greet() {
      const name = yield "name?";
      yield `Hi, ${name}`;
    }
    const g = greet();
    g.next(); // "name?"
    g.next("Ada"); // { value: "Hi, Ada", done: false }
  • return() method

    Terminates generator runs early, returning specified values immediately.

    const it = counter();
    it.next();
    it.return("end"); // { value: "end", done: true }
  • throw() method

    Injects exceptions directly into generators at the current yield line.

    function* safe() {
      try { yield 1; } catch (e) { yield e.message; }
    }
    const it = safe();
    it.next();
    it.throw(new Error("oops")); // value: "oops"
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Generators
Chapter 30 · Page 240
Advanced

JavaScript Generators

(continued)

Lazy Sequences

  • Infinite generators

    Computes unending data streams on demand with zero memory leaks.

    function* naturals() {
      let n = 1;
      while (true) yield n++;
    }
    const it = naturals();
    it.next().value; // 1
  • take() boundaries

    Extracts limited arrays from lazy sequences using break counters.

    function take(iterable, count) {
      const res = [];
      for (const v of iterable) {
        if (res.length >= count) break;
        res.push(v);
      }
      return res;
    }
    take(naturals(), 3); // [1, 2, 3]
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Generators
Chapter 30 · Page 241
Advanced

JavaScript Generators

(continued)

Custom Iterables

  • Symbol.iterator method

    Attaches generators to class object structures to allow for-of loops.

    class Range {
      constructor(start, end) {
        this.start = start;
        this.end = end;
      }
      *[Symbol.iterator]() {
        for (let i = this.start; i <= this.end; i++) {
          yield i;
        }
      }
    }
    [...new Range(1, 3)]; // [1, 2, 3]
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Generators
Chapter 30 · Page 242
Advanced

JavaScript Generators

(continued)

Delegation with yield*

  • Iterable forwarding

    Delegates execution directly to another iterable structure, avoiding loops.

    function* combine() {
      yield* [1, 2];
      yield* "ab";
    }
    [...combine()]; // [1, 2, "a", "b"]
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Generators
Chapter 30 · Page 243
Advanced

JavaScript Generators

(FAQ)

FAQ

Regular functions run to completion immediately when invoked. Generator functions, declared with function*, return an iterator instead. The function body runs only when calling .next().

The yield keyword pauses generator function execution and outputs a value to the caller. The generator remains frozen until the caller invokes .next() again.

Use yield* to forward values from another iterable, like an array or generator. This avoids manual loops and passes .next(), .return(), and .throw() down automatically.

The .return(value) method closes the generator early, returning the value. The .throw(error) method injects an exception at the current pause point, letting try/catch handle it.

Yes, they are. Assign a generator function to the object's Symbol.iterator property. The engine handles iterator tracking and value formats automatically under the hood.

Useful Cheatsheetsusefulcheatsheets.com
JavaScript Generators
Chapter 30 · Page 244
Advanced

JavaScript Generators

(In Practice)
In Practice

Lazy Fibonacci Sequence Generator

Generates an infinite Fibonacci sequence lazily using destructuring assignment and a custom take controller.

  1. 01Initialize variables to store the two initial sequence values.
  2. 02Establish an infinite loop that yields numbers on demand.
  3. 03Yield the current sequence value back to the caller.
  4. 04Calculate the subsequent numbers using destructuring array assignments.
  5. 05Pull a subset array of values without triggering infinite processing.
function* fibonacci() {
  let [prev, curr] = [0, 1];
  while (true) {
    yield curr;
    [prev, curr] = [curr, prev + curr];
  }
}

function take(generator, count) {
  const result = [];
  for (const value of generator) {
    if (result.length >= count) break;
    result.push(value);
  }
  return result;
}

console.log(take(fibonacci(), 5)); // [1, 1, 2, 3, 5]
Takeaway

Generators allow processing infinite data sequences safely by computing next values only when requested.