function* writes iterators for you
That hand-written next() in lesson 7-1 was clunky. A generator function (function*) builds the iterator for you:
- Calling it runs none of the body. It returns a generator object (an iterator).
- Each
next()runs the body until the nextyield, which pauses the function and hands out that value. - The function's local variables survive between pauses, like a closure that sleeps.
Generators earn their keep whenever a sequence is expensive, endless, or paged: ID factories, paginated API readers, streaming parsers. And they are iterable, so for...of consumes them directly (so does the spread syntax ..., which expands any iterable into individual values — Unit 8 covers it properly).
Code exercise · javascript
Run it. Nothing prints at creation. Each next() executes only up to the following yield, then freezes mid-function.
Lazy sequences
Because a generator only computes when asked, it can describe an infinite sequence safely:
function* naturals() { let n = 1; while (true) yield n++; }
No infinite loop actually runs. Values are produced one next() at a time, and the consumer decides when to stop. This lazy style shows up in real code as ID generators, paginated data readers, and streaming parsers.
Code exercise · javascript
Run it. The `while (true)` never spins out of control: each next() executes exactly one loop iteration and freezes at the yield. The consumer decides how much work ever happens.
Quiz
What does calling a generator function, like `steps()`, actually do?
Code exercise · javascript
Your turn. Write `function* evens(limit)` that yields the even numbers from 2 up to `limit`. The for...of should print 2, 4, 6.