- Home
- /
- Tutorials
- /
- JavaScript Tutorial
- /
- JavaScript Generator Communication
JavaScript Generators & Iterators
JavaScript Generator Communication
Values can be sent into a running generator through
next, not just read out of it.
A yield expression itself has a value, supplied by the next next() call.
This turns a generator into a genuine two-way conversation.
Example
Example
javascript
function* greeter() {
const name = yield "What is your name?";
yield "Hello " + name;
}
const g = greeter();
console.log(g.next().value);
console.log(g.next("Ada").value);The second call sends Ada in, which becomes the value of the first yield.
Passing Values In
The argument to next() becomes the result of the paused yield.
The very first next() call cannot pass a useful value, since nothing is paused yet.
return() and throw() can also be sent into a generator.
Syntax
Syntax
javascript
const value = yield something;
generator.next(valueToSend);The first next() only starts the generator running.
The First next Only Starts It
Anything passed to the first call is thrown away.
Example
Example
javascript
function* demo() {
const first = yield "step one";
console.log("received: " + first);
}
const g = demo();
g.next("ignored");
g.next("actually received");The generator had not reached a yield yet on the first call.
A Running Total
Each call both receives and returns a value.
Example
Example
javascript
function* adder() {
let total = 0;
while (true) {
total += yield total;
}
}
const g = adder();
g.next();
console.log(g.next(5).value);
console.log(g.next(10).value);The output is 5 then 15.
Ending Early with return
Calling return() on the iterator finishes it immediately.
Example
Example
javascript
function* countUp() {
yield 1;
yield 2;
yield 3;
}
const g = countUp();
console.log(g.next());
console.log(g.return("stopped early"));
console.log(g.next());Once returned, the generator reports done: true from then on.
Throwing Into a Generator
throw() raises an error at the paused yield, which the generator can catch.
Example
Example
javascript
function* demo() {
try {
yield 1;
yield 2;
} catch (error) {
yield "caught: " + error.message;
}
}
const g = demo();
g.next();
console.log(g.throw(new Error("stop")).value);The error was handled from inside the generator itself.
An Infinite Loop Is Safe Here
The while (true) above never actually runs forever.
A generator only advances when next() is called, so it pauses at each yield.
Example
Example
javascript
function* forever() {
let n = 0;
while (true) {
yield n;
n++;
}
}
const g = forever();
console.log(g.next().value);
console.log(g.next().value);
console.log(g.next().value);Nothing runs away, because each call only advances one step.
Complete Example
Complete Example
html
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Generator Communication</title>
</head>
<body>
<h1>Generator Communication</h1>
<p id="out"></p>
<script>
function* adder() {
let total = 0;
while (true) {
total += yield total;
}
}
const g = adder();
g.next();
const after5 = g.next(5).value;
const after10 = g.next(10).value;
document.getElementById("out").textContent =
"After adding 5: " + after5 + ", after adding 10 more: " + after10;
</script>
</body>
</html>Try It Yourself
Run the above example in the Try It Editor.
Try one more step:
Call g.next(20) again and see the running total.
Important Points
- The argument to
next()becomes the value of the pausedyield. - The first
next()call only starts the generator. return()ends the generator immediately.throw()raises an error inside the generator, which it can catch.- A
while (true)loop is safe becauseyieldpauses it.
Conclusion
Generators are not just for producing values; they can receive them too.
This is what makes them useful for coordinating step-by-step work.
The next lesson uses generators to build custom iterable objects.
