Stop 04 · JavaScriptTopics · 35/36

Generators

Part of the Frontend Developer Roadmap

In short

A normal function runs start to finish in one go. A generator can pause in the middle, hand you a value, and continue later from exactly where it stopped.

Functions (`function*`) that can pause and resume execution using `yield`, producing a sequence of values lazily instead of all at once. Generators are useful when values should be produced lazily, allowing consumers to pause iteration and request the next value only when needed.

The jaadu mascot binge-watches a show on the sofa with a remote and a bowl of popcorn.

Think of it like this

Binge-watching a web series

You watch one episode, close the app, and next time it picks up at episode 4, not from the start. yield is the end of an episode. next() is pressing "play next episode". The show remembers where you were.

Watch it happen

Pausing and resuming episodes()

Your code
episodes()

episodes()

1/7Calling the generator returns an iterator. No code inside has run yet.

The big ideas

What you need to know

function* and yield

The star marks a generator. Each yield pauses it and sends a value out.

Calling it doesn't run it

Calling a generator gives you an iterator object. The code inside starts only when you call next().

{ value, done }

Every next() returns an object with the yielded value and done, which becomes true when the generator finishes.

Lazy and endless

A generator makes values only when asked, so it can describe an infinite sequence without freezing.

See it in code

Walk through the code

js
1function* episodes() {2  yield "Ep 1";3  yield "Ep 2";4  return "Season over";5}6 7const show = episodes();     // nothing runs yet8console.log(show.next());    // { value: "Ep 1", done: false }9console.log(show.next());    // { value: "Ep 2", done: false }10console.log(show.next());    // { value: "Season over", done: true }11function* rollNumbers(start) {12  let n = start;13  while (true) yield n++;    // infinite, but lazy14}15const ids = rollNumbers(101);16console.log(ids.next().value, ids.next().value);  // 101 102

1/5function* makes a generator. Each yield is a pause point.

while (true) is safe here because yield pauses the loop each time. It only runs again when you ask for the next value.

Save yourself the pain

Common mistakes

Oops

Expecting for...of or spread to include the return value.

Do this instead

They stop as soon as done is true and ignore the returned value. Use yield for every value you want in the loop.

Oops

Spreading an infinite generator, like [...rollNumbers(1)].

Do this instead

That never ends and freezes the tab. Take only what you need with next() or a loop that breaks.

Your mission

Roll number machine

~20 min

Quick check

Using episodes() from above, what does [...episodes()] give?

Go deeper

  1. 1Write a simple generator that yields a sequence of numbers. Validate your understanding by applying it in a small practical example.
  2. 2Use a `for...of` loop to consume a generator's values. Verify the behavior with realistic data and handle the failure or empty state as well.
  3. 3Learn how generators power async iteration and libraries like Redux-Saga.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge