Generators in JavaScript
Introduction
A generator function (function*) returns an iterator you control with yield. Generators pause and resume execution—useful for lazy sequences, paginated data, and custom iteration without manual next() boilerplate. They build directly on the iterator protocol.
Prerequisites
Basic Generator
javascript
// function* defines a generator
function* threeLetters() {
yield "a";
yield "b";
yield "c";
}
const gen = threeLetters();
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());for...of Over Generators
javascript
function* range(start, end) {
for (let i = start; i <= end; i++) {
yield i;
}
}
for (const n of range(1, 5)) {
console.log(n);
}yield* Delegates to Another Iterable
javascript
function* flatten(arrays) {
for (const arr of arrays) {
yield* arr;
}
}
const values = [...flatten([[1, 2], [3]])];
console.log(values);Passing Values Into next
Advanced: gen.next(input) can influence generator state—common in coroutine-style libraries, less in everyday app code.
Generator as Iterable Object Method
javascript
class IdSeq {
*generate(count) {
for (let i = 1; i <= count; i++) {
yield `id-${i}`;
}
}
}
const seq = new IdSeq();
for (const id of seq.generate(3)) {
console.log(id);
}Async Generators (Preview)
async function* yields Promises—pairs with for await...of in async chapters. Same yield idea, different timing.
Mini Example: Read Pages Lazily
javascript
function* paginate(items, pageSize) {
for (let i = 0; i < items.length; i += pageSize) {
yield items.slice(i, i + pageSize);
}
}
const all = [1, 2, 3, 4, 5, 6, 7];
for (const page of paginate(all, 3)) {
console.log("page", page);
}FAQ
Generator vs normal function?
Generators return iterators and can pause; normal functions run to completion in one call.
Can generators replace Promises?
No—for async I/O use Promises/async—generators help iteration and lazy production.
Are generators slow?
Overhead is small; clarity and lazy evaluation are the main wins.