JavaScript Notes
Master JavaScript generators: function*, yield, next(), iterator protocol, lazy evaluation, infinite sequences, async generators, and top interview Q&A.
What are Generators?
A generator is a special type of function that can pause its execution in the middle and resume later from exactly where it paused. Regular functions run to completion — generators can yield control back, wait, and continue.
Every yield statement is a "pause point" that returns a value to the caller. The caller decides when to resume the generator by calling .next().
One-liner: A generator is a function you can pause and resume, returning values one at a time with yield.Generator Syntax
function* generatorName() {
yield value1;
yield value2;
return finalValue; // optional
}
const gen = generatorName(); // Does NOT run the function yet
const result1 = gen.next(); // Runs to first yield
const result2 = gen.next(); // Resumes to second yieldThe * after function marks it as a generator function.
Basic Example — Step by Step
function* countUp() {
console.log("Start");
yield 1;
console.log("After first yield");
yield 2;
console.log("After second yield");
yield 3;
console.log("Done");
}
const gen = countUp();
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());Start
{ value: 1, done: false }
After first yield
{ value: 2, done: false }
After second yield
{ value: 3, done: false }
Done
{ value: undefined, done: true }Execution trace:
gen.next() call 1:
→ Enters generator, runs "console.log('Start')"
→ Hits yield 1 → pauses, returns { value: 1, done: false }
gen.next() call 2:
→ Resumes after yield 1
→ Runs "console.log('After first yield')"
→ Hits yield 2 → pauses, returns { value: 2, done: false }
gen.next() call 3:
→ Resumes, runs "After second yield"
→ Hits yield 3 → pauses, returns { value: 3, done: false }
gen.next() call 4:
→ Resumes, runs "Done"
→ Reaches end → returns { value: undefined, done: true }Generator State Machine Diagram
The next() Return Object
Every .next() call returns an object with two properties:
{ value: any, done: boolean }| Property | Meaning |
|---|---|
value | The value from yield expression (or return) |
done | false while generator has more yields; true when finished |
Example — Infinite Sequence Generator
Generators are perfect for infinite sequences because they compute values lazily (only when asked):
1 2 3 4 5
Example — Sending Values INTO a Generator
next(value) can send a value back into the generator — received as the result of the yield expression:
function* calculator() {
const a = yield "Enter first number:";
const b = yield "Enter second number:";
return a + b;
}
const calc = calculator();
console.log(calc.next().value); // Starts gen, gets first prompt
console.log(calc.next(10).value); // Sends 10 → a=10, gets second prompt
console.log(calc.next(25)); // Sends 25 → b=25, returns sumEnter first number:
Enter second number:
{ value: 35, done: true }Example — Generator as Iterator (for...of)
Generators implement the Iterator protocol, so they work with for...of:
function* weekdays() {
yield "Monday";
yield "Tuesday";
yield "Wednesday";
yield "Thursday";
yield "Friday";
}
for (const day of weekdays()) {
console.log(day);
}Monday Tuesday Wednesday Thursday Friday
Also works with spread and destructuring:
["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
Example — yield* Generator Delegation
yield* delegates to another iterable or generator:
[0, 1, 2, 3, 4]
Example — Async-like Control with Generators
Before async/await, generators were used for async flow control:
function* fetchUserFlow() {
const user = yield fetchUser(1); // pause until user loaded
const posts = yield fetchPosts(user.id); // pause until posts loaded
return posts;
}Today async/await is cleaner, but generators powered early libraries like co.js and Redux Saga.
Real World Use Case — Paginated API
["A", "B", "C"] ["D", "E", "F"] ["G"]
Generator vs Regular Function vs Async Function
| Feature | Regular Function | Generator | Async Function |
|---|---|---|---|
| Can pause | ❌ | ✅ (yield) | ✅ (await) |
| Returns | Value | Iterator object | Promise |
| Multiple values | ❌ | ✅ (lazy) | ❌ |
| Resume with value | ❌ | ✅ (next(val)) | N/A |
| Use case | Normal logic | Lazy sequences, flow | Async operations |
Common Mistakes
❌ Mistake 1 — Calling Generator Function Without next()
function* gen() {
yield 1;
yield 2;
}
const g = gen();
console.log(g); // NOT 1 — it's the iterator object!Object [Generator] {}console.log(g.next().value); // Correct1
❌ Mistake 2 — Expecting First next() to Accept a Value
function* gen() {
const x = yield "ready";
console.log(x);
}
const g = gen();
g.next("ignored"); // First next() starts gen — this value is discarded!
g.next("received"); // This value becomes result of yieldreceived
The first .next() call starts execution and any value passed to it is discarded — there's no yield yet to receive it.
❌ Mistake 3 — Reusing an Exhausted Generator
function* gen() { yield 1; }
const g = gen();
g.next(); // { value: 1, done: false }
g.next(); // { value: undefined, done: true }
g.next(); // { value: undefined, done: true } — already done!Once a generator is exhausted (done: true), it never produces values again. Create a new instance if needed.
Interview Questions 🎯
Q1. What is a generator in JavaScript?
A generator is a special function (declared with function*) that can pause execution at yield statements and resume later from where it paused. Each .next() call on the returned iterator runs the generator body until the next yield, returning { value, done }.
Q2. What does yield do in a generator?
yield pauses the generator and sends a value to the caller (the value becomes the value in the returned { value, done } object). The generator resumes when .next() is called again, and the value passed to .next(val) becomes the result of the yield expression.
Q3. What is the iterator protocol?
An iterator must have a .next() method that returns { value, done }. Generators automatically implement this protocol, making them compatible with for...of, spread (...), destructuring, and Array.from().
Q4. What is the difference between a generator and a regular function?
- Regular function: Runs to completion in one call, returns one value
- Generator: Can pause and resume multiple times, yields multiple values lazily, returns an iterator object
Q5. What is lazy evaluation in generators?
Lazy evaluation means values are computed only when requested (on each .next() call). This allows generators to represent infinite sequences without computing all values upfront — memory efficient.
Q6. What is yield* (yield star)?
yield* delegates iteration to another iterable or generator. Instead of yield producing one value, yield* produces all values from the delegated iterable one by one.
Q7. How are generators used in Redux Saga?
Redux Saga uses generators to model side effects as a sequence of paused steps. Each yield in a saga represents waiting for an action or API call. The saga middleware drives the generator by calling .next() with results of each async operation.
Q8. What is an async generator?
1 2 3
An async generator combines async/await and generators — it can await promises and yield values, used with for await...of.
Key Takeaways 🔑
- Generators are functions with
function*that can pause atyieldand resume with.next() - Each
.next()returns{ value, done }—done: truewhen generator is exhausted - Values can be sent into a generator via
next(value)— received asyieldexpression result - Generators implement the iterator protocol — work with
for...of, spread, destructuring - Perfect for infinite sequences (lazy evaluation — compute only when needed)
yield*delegates to another iterable/generator- Modern use cases: lazy data pipelines, pagination, Redux Saga, state machines
Summary
JavaScript generators (function*) are special functions that can pause execution at yield statements and resume later, enabling lazy, on-demand value production. The generator function returns an iterator object whose .next() method drives execution step by step, returning { value, done } at each pause point. Generators are ideal for infinite sequences, paginated data, and complex async flow control. While async/await handles most async use cases today, generators remain important for lazy evaluation, custom iterables, and powerful libraries like Redux Saga.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for JavaScript Generators - Complete Guide with yield and Iteration.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this JavaScript Master Course topic.
Search Terms
javascript-complete-guide, javascript master course, javascript, complete, guide, advanced, generators, javascript generators - complete guide with yield and iteration
Related JavaScript Master Course Topics