Skip to main content

Generators in JavaScript

Generators are special functions that can pause execution and resume later, allowing you to produce a sequence of values over time rather than computing them all at once.

Basic Generator Syntax

Generators are defined using the function* syntax and use the yield keyword to pause execution.
Generators return an iterator object. Each call to next() resumes execution until the next yield statement.

Using Generators with for…of

Generators are iterable, so they work with for...of loops:

Infinite Sequences

Generators can produce infinite sequences because values are computed lazily:

Fibonacci Generator

Passing Values to Generators

You can pass values to a generator using next(value):
The first next() call starts the generator but doesn’t pass a value. Subsequent next(value) calls pass the value to the last yield.

yield* (Delegating to Another Generator)

You can delegate to another generator using yield*:

Practical Examples

ID Generator

Range Generator

Batch Processing

Tree Traversal

Async Data Fetching

Generator Methods

return()

Force a generator to complete:

throw()

Throw an error into the generator:

Lazy Evaluation

Generators enable lazy evaluation - values are computed only when needed:
This pipeline processes only the values needed, not all infinite numbers. Each operation is performed lazily.

Async Generators

Async generators combine generators with async/await:

Async Data Stream

Use Cases

Generate infinite sequences like IDs, random numbers, or mathematical sequences without consuming memory.
Process large datasets or streams one item at a time without loading everything into memory.
Create custom iterators for complex data structures like trees, graphs, or custom collections.
Implement state machines where each yield represents a state transition.
Coordinate multiple async operations with async generators, useful for pagination or streaming.

Best Practices

When working with large or infinite sequences, generators save memory by computing values on demand.
Generators are perfect for creating custom iterators for complex data structures.
Use generator pipelines to process data lazily, computing only what’s needed.
Use try/catch blocks inside generators to handle errors during iteration.