JSadvancedes2015

Generators and iterators

Sequences, paused on demand.

A generator is a function you can pause and resume. It hands back values one at a time, only computing the next when you ask β€” which makes lazy and even infinite sequences trivial.

The iterator protocol

An iterator is any object with a next() method that returns { value, done }. An iterable is any object exposing a [Symbol.iterator]() that returns such an iterator. for...of, spread, and destructuring all speak this protocol β€” implement it and your object plugs into all of them for free.

Generators write iterators for you

A function* returns a generator object that is both an iterator and an iterable. Each yield produces a value and pauses execution; the function's local state survives between calls. You almost never hand-roll { value, done } again β€” you yield and let the runtime build it.

Lazy by construction

Nothing in a generator runs until the first next() (or for...of step), and only as far as the next yield. That laziness is the whole point: you can describe an infinite sequence like the naturals or Fibonacci and pull just the prefix you need with a take helper, computing nothing more.

Delegation and two-way flow

yield* delegates to another iterable, flattening nested generators without manual loops. And yield is an expression: the value passed to .next(value) becomes the result of the paused yield, so data flows into a running generator as well as out of it.

Try it 6 examples

A lazy range generator

JSintro
Press Run to execute

for...of and spread both drive the same generator to produce [0,2,4,6,8] and [1,2,3,4], while the manual next() calls expose the raw protocol β€” two live values then {"done":true} (the value:undefined is dropped by JSON.stringify).