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
yieldkeyword 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 nextyield. Returns an object{ value: ..., done: ... }.value: The result of the expression afteryield.done:trueif the function code has finished, otherwisefalse.
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