Expecting generator body to execute on function call
Generator functions are lazy. Execution begins only when next is called on the returned iterator.
Fix: Always reason about generators as state machines driven by iterator calls.
Loading...
See how JavaScript generators work with an interactive visualization. Watch generator functions pause with yield and resume with .next(), step through the iterator protocol and two-way data flow.
Loading visualization...
Generators are pause-and-resume functions that produce iterator objects, enabling lazy evaluation, controlled sequencing, and two-way communication through next calls.
A generator function is declared with function* and returns an iterator when invoked. The function body does not run immediately on creation.
Each yield pauses execution and emits a value. Subsequent next calls resume from the exact paused point with preserved local state.
Generators unify iterable protocols and stateful control flow, making them useful for custom iteration, step-by-step workflows, and stream-like data consumption.
Interview framing: define Generators & Iterators in one sentence, then explain one concrete runtime behavior and one common pitfall with a short code example.
Generator functions are lazy. Execution begins only when next is called on the returned iterator.
Fix: Always reason about generators as state machines driven by iterator calls.
Once an iterator finishes, additional next calls stay done and do not restart the sequence.
Fix: Create a new iterator by calling the generator function again when a fresh run is needed.
Generators support throw and return, and failing to handle these channels can break control flow assumptions.
Fix: Design generator consumers to account for done state and possible thrown errors.
Common interview prompts with concise model answers.
No. Standard generators are synchronous. Async generators use async function* and integrate with for await...of.
function* ids() {
yield 1;
yield 2;
}
const it = ids();
console.log(it.next()); // { value: 1, done: false }Generator iterators implement the iterator protocol and are also iterable, so they work directly with for...of and spread in many cases.
Yes. The value passed to next becomes the result of the suspended yield expression inside the generator.
Use generators for lazy sequences, large or infinite streams, and scenarios where you need incremental processing without eager allocation.
Continue with these concepts to strengthen your mental model.
function* counter() { yield 1; yield 2; yield 3;} const gen = counter();console.log(gen.next());console.log(gen.next());console.log(gen.next());console.log(gen.next());not created
no calls yet
No output yet.