JavaScript · Advanced

Iterators and Generators

Generators are functions that can pause and resume. They make it easy to produce values one at a time — even endless streams.

Advanced 5 min Lesson 43 of 49 Runnable examples
Before you start:LoopsFunctions
0/49 in JavaScript
On this page · 5 min · Advanced

Learning objectives#

  • Write generator functions with function* and yield
  • Step through values with next()
  • Create lazy, infinite sequences
  • Make objects iterable with Symbol.iterator

Explanation#

An iterator is any object with a next() method that returns { value, done }. for…of and spread use iterators automatically.

A generator (function*) returns an iterator. Each yield hands out one value and pauses until the next request.

Because values are produced on demand, generators can describe infinite sequences without running forever.

Adding a [Symbol.iterator] generator method to an object makes it work with for…of and spread.

Code example: Countdowns, IDs and ranges#

JavaScriptCountdowns, IDs and ranges Runnable
function* countdown(from) {
  while (from > 0) yield from--;
  return 'Lift off!';
}
const it = countdown(3);
console.log(it.next());
console.log([...countdown(3)]);


function* ids() {
  let id = 1;
  while (true) yield `user-${id++}`;
}
const gen = ids();
console.log(gen.next().value, gen.next().value);


const range = {
  from: 1, to: 4,
  *[Symbol.iterator]() { for (let i = this.from; i <= this.to; i++) yield i; },
};
console.log([...range]);
Expected output
{ value: 3, done: false }
[ 3, 2, 1 ]
user-1 user-2
[ 1, 2, 3, 4 ]
Opens this example in the full playground

Step-by-step explanation#

  1. The first next() runs until the first yield and returns 3.
  2. Spreading collects all yielded values; the return value is not included.
  3. ids() is infinite, but only two values are requested, so it never hangs.
  4. range becomes iterable thanks to its Symbol.iterator generator.

Real-world use case#

Paging through API results one page at a time, generating unique IDs, or processing very large data sets without loading everything into memory.

Common mistakes#

Spreading an infinite generator

[...ids()] never finishes. Only take as many values as you need.

Forgetting the asterisk

yield only works inside function*.

Best practices#

  • Use generators for lazy or infinite sequences
  • Use for…of to consume iterators
  • Use async generators (async function*) for streams of async data
  • Keep generator logic simple

Remember this#

function* = a function with a pause button.

yield = “here’s one value, wake me when you need the next”.

next() returns { value, done }.

Practice exercise#

Your task: Write a generator evens() that yields 0, 2, 4, … forever, and log the first five values.

Show solution
JavaScript Runnable
function* evens() { let n = 0; while (true) { yield n; n += 2; } }
const g = evens();
for (let i = 0; i < 5; i++) console.log(g.next().value); // 0 2 4 6 8
Opens this example in the full playground

Mini quiz#

Iterators and Generators quizPredict the output Question 1 of 1

What does the second next() return?

function* g() { yield 'a'; }
const it = g();
it.next();
console.log(it.next());
Score so far: 0/0

Want more? Practise all JavaScript MCQs · JavaScript interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.