**Generator functions** (`function*`) produce iterators. Each **yield** pauses execution and returns a value. `next()` resumes from the last yield. They're lazy — values are computed on demand. Generators power **async/await** under the hood, are used for infinite sequences, and implement custom iterators.
1Understanding Generator Functions
Generator functions (function*) produce iterators. Each yield pauses execution and returns a value. next() resumes from the last yield. They're lazy — values are computed on demand. Generators power async/await under the hood, are used for infinite sequences, and implement custom iterators.
Generators are iterators — you can use them in for...of loops and with the spread operator.
// Infinite ID generator
function* idGenerator() {
let id = 1;
while (true) {
yield id++;
}
}
const gen = idGenerator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
// Never exhausts!2Practical Example
Here is a real-world application of Generator Functions showing how it is used in production JavaScript code.
// Use generator in for...of
function* fibonacci() {
let [a, b] = [0, 1];
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const fibs = [];
for (const n of fibonacci()) {
if (n > 100) break;
fibs.push(n);
}
console.log(fibs);3Best Practices
Follow these guidelines when working with Generator Functions:
1. Use generators for lazy/infinite sequences
2. Use yield* to delegate to another generator/iterable
3. Return from a generator triggers done: true
Tip: Generators are iterators — you can use them in for...of loops and with the spread operator.
// Infinite ID generator
function* idGenerator() {
let id = 1;
while (true) {
yield id++;
}
}
const gen = idGenerator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
// Never exhausts!