No Login Data Private Local Save

Generator Function Explorer - Online Step by Step

14
0
0
0
Generator Code
function* syntax
comma-separated
Step Explorer
No Generator
0 steps
next( )
return( )
throw( )
Create a generator and step through it
Frequently Asked Questions

A generator function is a special type of function declared with function* syntax. Unlike regular functions that run to completion, generators can be paused and resumed using the yield keyword. Each call to .next() resumes execution until the next yield or return, returning an object {value, done}. This makes them perfect for lazy evaluation, infinite sequences, and custom iterators.

yield pauses the generator function and returns a value to the caller. When .next() is called again, execution resumes from the exact point where it paused. You can also send values back into the generator by passing an argument to .next(value) — this value becomes the result of the yield expression inside the generator. This enables powerful two-way communication patterns.

Regular functions execute completely when called and return a single value. Generator functions return a Generator object (an iterator) and can yield multiple values over time. Key differences: (1) Generators maintain their internal state between calls, (2) they're lazy — values are produced on-demand, (3) they support two-way communication via .next(val), and (4) they can be terminated early with .return() or injected with errors via .throw().

A generator has three possible states: Suspended (paused at a yield, ready to resume), Closed (completed via return or exhausted all yields), and Running (actively executing code between yield points — though this state is only observable from within the generator itself). You can check if a generator is done by inspecting the done property of the result from .next().

Generators excel in many scenarios: Lazy iteration over large datasets without loading everything into memory, infinite sequences (like ID generators or Fibonacci), custom iterators for complex data structures, state machines, async flow control (they were the precursor to async/await), data pipelines with yield* delegation, and coroutine-like patterns for cooperative multitasking. Libraries like Redux-Saga heavily rely on generators for managing side effects.

yield* delegates execution to another iterable (often another generator). It essentially flattens the iteration: instead of yielding the iterable object itself, it yields each value from the delegated iterable one by one. This is incredibly useful for composing generators, creating data processing pipelines, and recursively traversing tree structures. Values passed via .next() and errors via .throw() are also transparently forwarded to the delegated generator.

Async/await was heavily inspired by generators. Early async patterns used generators with promise-based runners (like co library). An async function is conceptually similar to a generator that yields promises, with an automatic runner that calls .next() each time a promise resolves. The key difference: async functions always return promises and are designed specifically for asynchronous operations, while generators are synchronous pausing mechanisms that can be adapted for async use cases.