Docs

13.5-Generators

17.5 Generators

Overview

Generators are special functions that can pause execution and resume later, yielding multiple values over time. They provide a powerful way to create iterators and handle asynchronous operations.

Generator Syntax

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                      Generator Function                                 │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                         │
│  // Generator function declaration                                      │
│  function* generatorName() {                                            │
│      yield value1;                                                      │
│      yield value2;                                                      │
│      return finalValue;                                                 │
│  }                                                                      │
│                                                                         │
│  // Generator method in object                                          │
│  const obj = {                                                          │
│      *generator() {                                                     │
│          yield 1;                                                       │
│      }                                                                  │
│  };                                                                     │
│                                                                         │
│  // Generator method in class                                           │
│  class MyClass {                                                        │
│      *generator() {                                                     │
│          yield 1;                                                       │
│      }                                                                  │
│  }                                                                      │
│                                                                         │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

How Generators Work

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                    Generator Execution                                  │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                         │
│  function* counter() {           const gen = counter();                 │
│      console.log('Start');                                              │
│      yield 1;            ──→     gen.next() → {value: 1, done: false}   │
│      console.log('After 1');     // 'Start' printed                     │
│      yield 2;            ──→     gen.next() → {value: 2, done: false}   │
│      console.log('After 2');     // 'After 1' printed                   │
│      return 3;           ──→     gen.next() → {value: 3, done: true}    │
│  }                               // 'After 2' printed                   │
│                                  gen.next() → {value: undefined, done}  │
│                                                                         │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

yield vs return

Featureyieldreturn
Pauses executionYesNo (terminates)
ResumesYesNo
done propertyfalsetrue
Can be multipleYesOnly one (last)

Generator Methods

const gen = myGenerator();

gen.next(value); // Resume execution, optionally pass value
gen.return(value); // Terminate generator with value
gen.throw(error); // Throw error at current yield

yield* Delegation

function* delegating() {
  yield* [1, 2, 3]; // Delegate to array
  yield* 'abc'; // Delegate to string
  yield* otherGenerator(); // Delegate to another generator
}

Use Cases

  1. •Custom iterators - Simplified iterator creation
  2. •Lazy evaluation - Generate values on demand
  3. •Infinite sequences - Memory-efficient streams
  4. •State machines - Manage complex state
  5. •Async flow control - With async generators

Generators Are Iterables

function* gen() {
  yield 1;
  yield 2;
}

for (const value of gen()) {
  console.log(value); // 1, 2
}

console.log([...gen()]); // [1, 2]

Summary

  • •Generators use function* syntax
  • •yield pauses and returns a value
  • •next() resumes execution
  • •Generators are iterables
  • •yield* delegates to other iterables
  • •Great for lazy sequences and iterators
.5 Generators - JavaScript Tutorial | DeepML