2 min read

Generators

Generators are a special class of functions that simplify the task of writing iterators. A generator is a function that can stop midway and then continue from where it stopped.

1. The Concept

Normal functions run to completion. Generators allow you to pause execution and resume it later. This is useful for custom iterators, lazy evaluation, and controlling asynchronous flows.

2. Syntax

  • Declaration: Use function* (with an asterisk).
  • Pause: Use the yield keyword to return a value and pause execution.
function* simpleGenerator() {
  yield 1;
  yield 2;
  yield 3;
}

const generatorObject = simpleGenerator();

console.log(generatorObject.next()); // { value: 1, done: false }
console.log(generatorObject.next()); // { value: 2, done: false }
console.log(generatorObject.next()); // { value: 3, done: false }
console.log(generatorObject.next()); // { value: undefined, done: true }

3. How it Works

When called, a generator function does not execute its code. Instead, it returns a special object, called a Generator Object, which manages the execution.

  • next(): Resumes execution until the next yield. Returns an object { value: ..., done: ... }.
  • value: The result of the expression after yield.
  • done: true if the function code has finished, otherwise false.

4. Infinite Streams

Since generators evaluate lazily (only when next() is called), you can create infinite loops without crashing the browser.

function* idMaker() {
  let index = 0;
  while (true) {
    yield index++;
  }
}

const gen = idMaker();

console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
// ...

5. Two-way Communication

You can pass values back into the generator using next(value). The value passed becomes the result of the yield expression.

function* listener() {
  console.log("Start");
  const input = yield "Waiting for input...";
  console.log("Received:", input);
}

const gen = listener();
console.log(gen.next().value); // Start, "Waiting for input..."
gen.next("Hello!");            // Received: Hello!

6. yield* (Delegation)

You can delegate execution to another generator using yield*.

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

function* generateAll() {
  yield* generateSequence();
  yield 3;
}

for (let value of generateAll()) {
  console.log(value); // 1, 2, 3
}

programming/javascript/vanilla/javascript programming/javascript/vanilla/es6-features