Compile Ready
Module 11 · Advanced JavaScript

Generators

Advanced14m read22m practice36m total
GeneratorsIteratorsLazy Evaluationfunction*

Introduction

A generator is a function that can pause and resume. It is declared with function*, produces values with yield, and returns an iterator whose next() method advances execution.

Generators make lazy sequences natural: ranges, paginated adapters, infinite counters, parser streams, cooperative workflows, and custom iteration protocols.

Why This Matters

Interviewers use generators to test execution suspension, the iterator protocol, and lazy evaluation. They also connect cleanly to infinite sequences and composing iterables with yield*.

Theory

Execution model

Calling a generator function does not run its body immediately. It returns a generator object. The body starts only when next() is called. Each yield pauses execution and returns { value, done: false }. A return or falling off the end returns { value, done: true }.

Lazy sequences

Generators compute values on demand. That means you can model large or infinite sequences without allocating all values up front. Consumers decide how many values to take.

Sending values back in

next(value) sends a value into the paused generator as the result of the current yield expression. The first next starts the generator and its argument is ignored.

Delegation with yield*

yield* iterable forwards iteration to another iterable. It is useful for flattening generators or composing smaller sequence producers.

Visual Diagrams

Generator pause and resume
call generator -> returns iterator, body not run
next() -> run until first yield -> pause
next() -> resume after yield -> pause at next yield
next() -> resume -> return done true

The call stack re-enters the generator body on each `next()`.

Code Examples

Finite and infinite generators

The infinite generator is safe because consumers can stop after taking a limited number of values.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1function* steps() {
2 console.log('start');
3 yield 'A';
4 console.log('middle');
5 yield 'B';
6 return 'C';
7}
8
9var iterator = steps();
10console.log('created');
11console.log(iterator.next().value);
12console.log(iterator.next().value);
13console.log(iterator.next().value);

Coding Exercises

Build lazy range and take helpers

Medium

Implement range(start, end, step) as a generator and take(iterable, count) as a helper that consumes at most count values from any iterable.

Interview Questions

1What happens when you call a generator function?

The body does not execute immediately. The call returns a generator object that implements the iterator protocol. Execution begins on the first next() and pauses at each yield.

Asked at:GoogleBloombergMicrosoft

Follow-ups

  • What does `next(value)` do?
  • How does `yield*` work?
2Why are generators useful for infinite sequences?

They produce values lazily. Only requested values are computed, so an infinite sequence can be represented safely as long as consumers stop after a finite number of next() calls.

Quiz

1. When does a generator function body start executing?

Summary

  • Generators are declared with `function*` and pause at `yield`.
  • Calling a generator returns an iterator without running the body immediately.
  • Generators are ideal for lazy and infinite sequences.
  • `yield*` delegates iteration to another iterable.

Cheat Sheet

Declare: function* name().

Pause: yield value returns { value, done: false }.

Finish: return value returns { value, done: true }.

Lazy: body runs only as consumers call next().

Compose: yield* otherIterable.