Generators for lazy sequences
| 1 min read
Generators (function*) produce values one at a time, only when asked. The most common use I have for them is generating unique IDs without keeping a counter floating around in module scope.
function* idGen(prefix = "id") {
let i = 0;
while (true) yield `${prefix}_${++i}`;
}
const nextId = idGen("user");
nextId.next().value; // "user_1"
nextId.next().value; // "user_2"
nextId.next().value; // "user_3"
The while (true) looks scary but itโs fine, yield pauses the function and hands control back to the caller. The next .next() resumes it.
You can do the same for infinite sequences. Fibonacci as a one-screen example:
function* fib() {
let [a, b] = [0, 1];
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const f = fib();
[
f.next().value,
f.next().value,
f.next().value,
f.next().value,
f.next().value,
];
// [0, 1, 1, 2, 3]
Generators are also iterable, so you can use them with for...of and spread ๐คฏ, just remember infinite ones will, well, never finish:
for (const id of idGen()) {
if (id === "id_5") break;
console.log(id);
}
Lazy, stateful, no globals.