Course outline · 0% complete

0/27 lessons0%

Course overview →

Generators: pausable functions

lesson 7-2 · ~11 min · 18/27

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 next yield, 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.