⚡

How to Use Generators in JavaScript

JavaScriptAdvanced

Create iterable sequences with generator functions.

Code Example

JavaScript
// Basic generator
function* countUp(max) {
  let count = 0;
  while (count < max) {
    yield count;
    count++;
  }
}

const counter = countUp(5);
console.log(counter.next()); // { value: 0, done: false }
console.log(counter.next()); // { value: 1, done: false }
console.log(counter.next()); // { value: 2, done: false }

// Iterate with for...of
for (const num of countUp(3)) {
  console.log(num); // 0, 1, 2
}

// Infinite generator
function* fibonacci() {
  let a = 0, b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

const fib = fibonacci();
console.log(fib.next().value); // 0
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2

// Generator with parameters
function* range(start, end, step = 1) {
  for (let i = start; i < end; i += step) {
    yield i;
  }
}

console.log([...range(0, 10, 2)]); // [0, 2, 4, 6, 8]

// yield* delegates to another generator
function* inner() {
  yield "a";
  yield "b";
}

function* outer() {
  yield 1;
  yield* inner();
  yield 2;
}

console.log([...outer()]); // [1, "a", "b", 2]

// Two-way communication
function* conversation() {
  const name = yield "What is your name?";
  const age = yield `Hello ${name}, how old are you?`;
  return `So you're ${age} years old!`;
}

const conv = conversation();
console.log(conv.next().value); // "What is your name?"
console.log(conv.next("Alice").value); // "Hello Alice, how old are you?"
console.log(conv.next(30).value); // "So you're 30 years old!"

// Async generator
async function* fetchPages(url) {
  let page = 1;
  while (true) {
    const response = await fetch(`${url}?page=${page}`);
    const data = await response.json();
    if (data.length === 0) break;
    yield data;
    page++;
  }
}

// Generator as iterator
class Range {
  constructor(start, end) {
    this.start = start;
    this.end = end;
  }
  
  *[Symbol.iterator]() {
    for (let i = this.start; i <= this.end; i++) {
      yield i;
    }
  }
}

const range2 = new Range(1, 5);
console.log([...range2]); // [1, 2, 3, 4, 5]

Explanation

Generator functions use function* and yield. Return iterator with next() method. Use for...of to iterate. yield* delegates to another generator. Can send values with next(value).

Related Tutorials