Ever had a situation where you needed to process a large dataset step-by-step instead of loading everything at once?
Maybe you were paginating API results, streaming data, or building a custom loop that pauses between steps.
Traditional loops like for or
while run immediately from start
to finish. But sometimes you want
control — the ability to
pause execution and continue later.
That’s exactly where Iterators and Generators shine in JavaScript.
They allow you to produce values on demand, instead of generating everything at once.
And once you understand them, you'll start seeing opportunities to use them everywhere.
Let’s break it down.
🔁 Understanding Iterators
An iterator is an object that defines a sequence and provides a method to get the next value.
In JavaScript, an iterator must implement a method called:
next()
Each time next() runs, it
returns an object like this:
{
value: something,
done: true | false
}
Simple Iterator Example
const numbers = [10, 20, 30];
const iterator = numbers[Symbol.iterator]();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
Output:
{ value: 10, done: false }
{ value: 20, done: false }
{ value: 30, done: false }
{ value: undefined, done: true }
Each call moves the iterator forward.
This is actually what powers loops like:
for (const num of numbers) {
console.log(num);
}
The for...of loop internally
uses an iterator.
🧩 What Are Generators?
Writing iterators manually can get messy quickly.
That’s why JavaScript introduced Generators.
A generator is simply a special function that can pause and resume execution.
You create one using the
function* syntax.
Basic Generator Example
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
const gen = numberGenerator();
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
Output:
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: undefined, done: true }
The yield keyword pauses
execution and returns a value.
When next() is called again,
the function
continues exactly where it stopped.
Think of it like a bookmark inside a function.
⚡ Using Generators with Loops
Generators work beautifully with
for...of.
function* colors() {
yield "red";
yield "green";
yield "blue";
}
for (const color of colors()) {
console.log(color);
}
Output:
red
green
blue
JavaScript automatically handles the iterator behind the scenes.
This makes generators extremely clean to use.
🛠️ Practical Example — Infinite ID Generator
One practical use case is generating IDs.
function* idGenerator() {
let id = 1;
while (true) {
yield id++;
}
}
const generateId = idGenerator();
console.log(generateId.next().value);
console.log(generateId.next().value);
console.log(generateId.next().value);
Output:
1
2
3
This generator can run forever, but only produces values when requested.
No unnecessary computation.
Perfect for things like:
- unique IDs
- pagination systems
- lazy data processing
💡 Real Developer Insight
Generators are incredibly useful when dealing with large datasets or streaming operations.
For example, imagine processing thousands of log entries.
Instead of loading everything into memory, a generator can yield entries one by one.
This keeps memory usage low and makes the code easier to reason about.
In many backend systems and Node.js tools, generators are used to implement lazy evaluation — doing work only when it's needed.
Once you start thinking in terms of "generate values when requested", generators become a powerful mental model.
⚠️ Common Developer Mistakes
1. Forgetting to call
next()
Generators don't run automatically. They execute only when
next() is called.
2. Confusing yield with
return
return ends the generator
permanently.
yield pauses it and allows
execution to continue later.
3. Expecting generators to run like normal functions
Generators don't produce values immediately. They create an iterator that controls execution.
4. Overusing generators
Generators are powerful, but they shouldn't replace simple loops unless there’s a clear benefit.
🚀 Best Practice Summary
✅ Use generators when you need lazy evaluation or step-by-step value
generation
✅ Prefer generators over manual iterator implementations for cleaner code
✅ Combine generators with
for...of for readable
iteration
✅ Use generators for infinite sequences or on-demand data generation
✅ Avoid generators when a simple array or loop solves the problem
0 Comments