Episode 11 of 11
Generators
Learn generator functions — pausable functions with function* and yield that produce values on demand.
Generators
Generators are special functions that can be paused and resumed. Instead of returning a single value, they produce a sequence of values on demand using the yield keyword.
Basic Syntax
// Generator function (note the *)
function* myGenerator() {
yield "first";
yield "second";
yield "third";
}
// Create a generator object
const gen = myGenerator();
// Call .next() to get each value:
gen.next(); // { value: "first", done: false }
gen.next(); // { value: "second", done: false }
gen.next(); // { value: "third", done: false }
gen.next(); // { value: undefined, done: true }
Each yield pauses the function and returns a value. Calling .next() resumes from where it paused.
How Generators Work
- Calling
myGenerator()doesn't execute the body — it returns a generator object - Each
.next()runs the code until the nextyield - The function pauses at each
yield - When there are no more
yieldstatements,donebecomestrue
Generators are Iterables
function* colors() {
yield "red";
yield "green";
yield "blue";
}
// for...of automatically calls .next()
for (const color of colors()) {
console.log(color);
}
// "red"
// "green"
// "blue"
// Spread operator works too
const allColors = [...colors()];
// ["red", "green", "blue"]
// Destructuring
const [first, second] = colors();
// first = "red", second = "green"
Infinite Sequences
function* naturalNumbers() {
let n = 1;
while (true) {
yield n++;
}
}
const nums = naturalNumbers();
nums.next().value; // 1
nums.next().value; // 2
nums.next().value; // 3
// Goes on forever — but only computes on demand!
Without generators, an infinite loop would freeze your program. With generators, values are computed lazily — only when requested.
Passing Values INTO a Generator
function* conversation() {
const name = yield "What is your name?";
const age = yield `Hello, ${name}! How old are you?`;
yield `${name}, age ${age}. Got it!`;
}
const chat = conversation();
chat.next(); // { value: "What is your name?", done: false }
chat.next("Alice"); // { value: "Hello, Alice! How old are you?", done: false }
chat.next(25); // { value: "Alice, age 25. Got it!", done: false }
chat.next(); // { value: undefined, done: true }
The argument you pass to .next(value) becomes the return value of the yield expression inside the generator.
Practical: ID Generator
function* idGenerator(prefix = "id") {
let id = 1;
while (true) {
yield `${prefix}_${id++}`;
}
}
const userId = idGenerator("user");
userId.next().value; // "user_1"
userId.next().value; // "user_2"
userId.next().value; // "user_3"
const orderId = idGenerator("order");
orderId.next().value; // "order_1"
orderId.next().value; // "order_2"
Practical: Range Function
function* range(start, end, step = 1) {
for (let i = start; i <= end; i += step) {
yield i;
}
}
[...range(1, 5)]; // [1, 2, 3, 4, 5]
[...range(0, 10, 2)]; // [0, 2, 4, 6, 8, 10]
[...range(10, 50, 10)]; // [10, 20, 30, 40, 50]
yield* — Delegating to Another Generator
function* inner() {
yield "a";
yield "b";
}
function* outer() {
yield 1;
yield* inner(); // Delegate to inner generator
yield 2;
}
[...outer()]; // [1, "a", "b", 2]
yield* delegates to another iterable (generator, array, string) and yields each of its values.
Generator vs Regular Function
| Feature | Regular Function | Generator |
|---|---|---|
| Execution | Runs to completion | Pausable and resumable |
| Return values | One value (or array) | Multiple values on demand |
| Syntax | function name() | function* name() |
| Keyword | return | yield (and return) |
| Iterable | No | Yes |
| Infinite sequences | Cannot | Can (lazy evaluation) |
Key Takeaways
- Generators use
function*andyieldto produce values on demand .next()returns{ value, done }— resumes execution until the nextyield- Generators are iterable — work with
for...of, spread, and destructuring - They enable infinite sequences with lazy evaluation
- Values can be passed into generators via
.next(value) yield*delegates to another generator or iterable- Common uses: ID generators, range functions, pagination, async flow control