- Home
- /
- Tutorials
- /
- JavaScript Tutorial
- /
- JavaScript Generator Functions
JavaScript Generators & Iterators
JavaScript Generator Functions
A generator function can pause with
yieldand resume later, producing one value at a time.
Writing an iterator by hand, as in the first lesson, is fiddly to get right.
A generator writes the same thing as an ordinary-looking function.
Example
Example
javascript
function* countTo(max) {
for (let i = 1; i <= max; i++) {
yield i;
}
}
const counter = countTo(3);
console.log(counter.next());
console.log(counter.next());Calling a generator function does not run it; it returns an iterator.
function* and yield
The * after function marks it as a generator.
yield pauses execution and hands out a value.
Calling next() resumes it from exactly where it paused.
Syntax
Syntax
javascript
function* name() {
yield value;
}Calling the generator function returns an iterator, not a result.
Nothing Runs Until next Is Called
The body does not start executing when the function is called.
Example
Example
javascript
const order = [];
function* demo() {
order.push("started");
yield 1;
}
const g = demo();
order.push("called, not started yet");
g.next();
console.log(order.join(" | "));The output is called, not started yet | started.
Using for of on a Generator
A generator's return value is iterable, so it works directly in a loop.
Example
Example
javascript
function* countTo(max) {
for (let i = 1; i <= max; i++) {
yield i;
}
}
const values = [];
for (const n of countTo(3)) {
values.push(n);
}
console.log(values.join(","));No manual next() calls were needed.
The Final done Value
A return inside a generator sets the last value and ends it.
Example
Example
javascript
function* demo() {
yield 1;
yield 2;
return "finished";
}
const g = demo();
console.log(g.next());
console.log(g.next());
console.log(g.next());The last call has done: true and carries the returned value.
Spreading a Generator
Because it is iterable, spread collects every yielded value.
Example
Example
javascript
function* countTo(max) {
for (let i = 1; i <= max; i++) {
yield i;
}
}
const values = [...countTo(4)];
console.log(values.join(","));The output is 1,2,3,4.
Delegating with yield*
One generator can hand off to another entirely.
Example
Example
javascript
function* inner() {
yield "a";
yield "b";
}
function* outer() {
yield 1;
yield* inner();
yield 2;
}
console.log([...outer()].join(","));The output is 1,a,b,2.
Complete Example
Complete Example
html
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Generator Functions</title>
</head>
<body>
<h1>Generator Functions</h1>
<p id="out"></p>
<script>
function* countTo(max) {
for (let i = 1; i <= max; i++) {
yield i;
}
}
const values = [];
for (const n of countTo(5)) {
values.push(n);
}
document.getElementById("out").textContent = values.join(", ");
</script>
</body>
</html>Try It Yourself
Run the above example in the Try It Editor.
Try a bigger range:
Change 5 to 10 and see the list grow.
Important Points
function*declares a generator.yieldpauses and hands out a value.- Calling a generator function returns an iterator without running the body.
- A generator works directly with
for ofand spread. yield*delegates to another generator.
Conclusion
Generators are the practical way to build an iterator.
They read like an ordinary loop, but pause instead of running to completion.
The next lesson covers passing values back in as it runs.
