I am reading "The JavaScript Handbook" by Flavio Scopes. He introduces the concept of Generators.
function* calculator(input) {
var doubleThat = 2 * (yield(input / 2))
var another = yield(doubleThat)
return (input * doubleThat * another)
}
// He then runs the following code
const calc = calculator(10)
console.log(calc.next())
{value: 5, done: false}
calc.next(7);
{value: 14, done: false}
I understand the first output, but I don't understand the second one. Why is the output 14?
My understanding is that the next time .next()
is called on calc
, it should continue on the line AFTER the one on which it last paused.
Well, that line is this one: var another = yield(doubleThat)
and the value of the variable doubleThat
at that point should be 10, so I'm expecting the second yield to return an object with a value of 10.
I don't think the example in the book is a good one, as I understand the concept of Generators (Python) and Iterators (C++/Python), and I understand other Javascript examples of Generators - but I simply do not understand what is going on here.
Can anyone explain why the value returned after calc.next(7)
is 14?
A Javascript Code Generator is a tool that makes coding process faster. Zontroy provides such a generator. It produces code in a manner that it is like written by a developer. A javascript developer can generate tons of code using Zontroy Code Generator.
Syntax : // An example of generator function function* gen(){ yield 1; yield 2; ... ... } The Generator object is returned by a generating function and it conforms to both the iterable protocol and the iterator protocol.
To create a generator, we need a special syntax construct: function* , so-called “generator function”. Generator functions behave differently from regular ones. When such function is called, it doesn't run its code. Instead it returns a special object, called “generator object”, to manage the execution.
The call to .next(7)
provides a value for that first yield
expression, overriding the value 5
that it previously computed and returned. It's a two-way relationship. The first yield
"pauses" mid-expression, to be clear. Execution continues from inside that expression, not the next statement.
That said, I am inclined to agree that it's a questionable example, because I'm not sure that's a realistic situation. It's hard to imagine code like that constructed on purpose for some real application.
function* calculator(input) {
var doubleThat = 2 * (yield(input / 2))
var another = yield(doubleThat)
return (input * doubleThat * another)
}
const calc = calculator(10)
console.log(calc.next());
At that point you reach the first yield that is 10 / 2
.
Then
calc.next(7);
the code is now this
var doubleThat = 2 * (7) // yield expression transformed into 7
Therefor the value is 14
You can gain some insight with the debugger
function* calculator(input) {
var doubleThat = 2 * (yield(input / 2))
var another = yield(doubleThat)
return (input * doubleThat * another)
}
const calc = calculator(10)
debugger;
console.log(calc.next());
debugger;
console.log(calc.next(7))
The only weird thing is that when you enter the second next the debugger gets you on the second line of the function, seemingly not executing the 2*7
. I think that's just seemingly because it doesn't stop mid expression but I could be wrong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With