Difficulty: Advanced
What are generator functions in JavaScript? What are their use cases?
Generator functions (function*) return a Generator object that implements the iterator protocol. They can pause execution at each yield expression and resume from that point.
How they work: - Calling a generator function returns a generator object (does not execute the body) - Each call to .next() runs the body until the next yield - .next() returns { value, done } - yield* delegates to another iterable
Use cases: lazy infinite sequences, custom iterables, async control flow, cooperative multitasking, and data pipeline transformations.
function* counter(start = 0) {
while (true) {
yield start++;
}
}
const gen = counter(1);
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
function take(gen, n) {
const result = [];
for (const val of gen) {
result.push(val);
if (result.length >= n) break;
}
return result;
}
console.log(take(counter(1), 5));
Generators produce values lazily - the infinite loop never runs out of control because execution pauses at each yield.
function* dialog() {
const name = yield 'What is your name?';
const age = yield `Hello ${name}! How old are you?`;
yield `${name} is ${age} years old.`;
}
const d = dialog();
console.log(d.next().value);
console.log(d.next('Alice').value);
console.log(d.next(30).value);
function* flatten(arr) {
for (const item of arr) {
if (Array.isArray(item)) yield* flatten(item);
else yield item;
}
}
console.log([...flatten([1, [2, [3, 4]], 5])]);
Passing a value to next() sends it back as the result of the yield expression. yield* delegates to another generator or iterable.
function*, yield, Iterator Protocol, Lazy Evaluation