Skip to content

JavaScript Tutorial Iterators and Generators

JavaScript Generators and yield

Lesson 182 of 258 2 min read By Deepak Paswan Updated Oct 4, 2026

A generator is a special function that can pause in the middle and resume later. It is declared with function* and gives out values one at a time with yield.

script.js
JS
function* count() {
  console.log("start");
  yield 1;
  console.log("after first yield");
  yield 2;
  console.log("after second yield");
  yield 3;
}

const generator = count();      // nothing runs yet

console.log(generator.next()); // → { value: 1, done: false }   (runs until the first yield)
console.log(generator.next()); // → { value: 2, done: false }
console.log(generator.next()); // → { value: 3, done: false }
console.log(generator.next()); // → { value: undefined, done: true }

Calling a generator function does not run its body. It returns a generator object (which is an iterator). Each next() runs the code until the next yield, hands the value out, and pauses there.

Using it in loops

A generator object is iterable, so for...of and spread work.

script.js
JS
function* letters() {
  yield "a";
  yield "b";
  yield "c";
}

for (const letter of letters()) {
  console.log(letter);
}

console.log([...letters()]); // → ["a", "b", "c"]

Infinite sequences

Because values are produced on demand, a generator can describe an endless sequence without using endless memory.

script.js
JS
function* naturals() {
  let n = 1;
  while (true) {
    yield n++;
  }
}

for (const n of naturals()) {
  if (n > 5) break;            // stop it yourself!
  console.log(n);              // 1, 2, 3, 4, 5
}

(The editor stops after 300 console lines, but an infinite loop without break would freeze a normal page. Always have a way out.)

Taking just what you need

script.js
JS
function* naturals() {
  let n = 1;
  while (true) yield n++;
}

function take(iterable, count) {
  const result = [];
  for (const item of iterable) {
    if (result.length >= count) break;
    result.push(item);
  }
  return result;
}

console.log(take(naturals(), 4)); // → [1, 2, 3, 4]

yield* delegates to another iterable

script.js
JS
function* abc() {
  yield "a";
  yield "b";
}

function* all() {
  yield* abc();      // yields everything from abc()
  yield "c";
}

console.log([...all()]); // → ["a", "b", "c"]

Generators are lazy

Nothing is computed until someone asks for the next value. That is the key idea, and the reason to use them: big or infinite data, and step-by-step processes.

info
Syntax reminders
The star can sit on either side of the space: function* name() is the common style. In object and class methods, write *name() { ... }.