yield and Generator Control Flow
In short: yield is a two-way channel, not just an exit. It sends
a value out to whoever called .next() — but it's also an expression
that pauses there, waiting to be given a value back. Whatever you pass
into the following .next(v) call becomes that paused yield
expression's own result. Beyond stepping through with .next(), two more
methods control a generator from outside: .return(v) stops it early, and
.throw(err) raises an error at the exact point it's paused, letting the
generator's own try/catch handle it if it has one.

Pass answers back into a paused generator
The argument to .next(v) becomes the value of the yield expression
that's currently paused — a real, two-way conversation:
it.next() (no argument) starts the generator and pauses at the first
yield, returning { value: "What's your name?", done: false } — its
argument is ignored, since there's no paused yield yet to receive it.
it.next("Asha") supplies "Asha" as that paused yield's result, which
is assigned to name, and the generator runs on to the next yield.
it.next("great") finishes it the same way, returning
{ value: "Asha says: great", done: true } from the return statement.
Stop a generator early with return()
.return(v) ends the generator immediately, wherever it's currently
paused — as if a return v; had been written right there:
After one yield, .return("stopped early") finishes the generator on
the spot, returning { value: "stopped early", done: true } — "Red Dawn" and "Green Tide" are never reached. Any further .next() calls
after that just return { value: undefined, done: true }, the same as a
normally finished generator.
Raise an error inside a paused generator
.throw(err) makes the paused yield throw err, right there inside
the generator — its own try/catch can catch it, exactly like a
synchronous error:
After the first yield, .throw(new Error("skip track")) raises that
error exactly where the generator is paused. Because that spot sits inside
a try block, the generator's own catch handles it, logs the message,
and yields "recovered" instead of the error propagating out to the
caller.
Quick practice
In const name = yield "question"; ..., what does the next(v) argument that resumes this line become?
Why is the argument to the very first .next() call on a fresh generator always ignored?
What does generator.return("done") do when called while the generator is paused at a yield?
What does generator.throw(err) do?
After generator.return() has finished a generator, what does a further .next() call return?
🎯 Your turn
Trace
function* chat() { const name = yield "What's your name?"; const mood = yield \Hi ${name}, how are you?`; return `${name} says: ${mood}`; } const it = chat(); it.next(); it.next("Asha"); it.next("great");and explain what eachnext()call returns, and specifically what value the firstyield` expression evaluates to and why.
Write your explanation and submit it — there's no code to run here, just your reasoning.
