Learning about generators I've got this example from MDN :
function* fibonacci() {
var fn1 = 0;
var fn2 = 1;
while (true) {
var current = fn1;
fn1 = fn2;
fn2 = current + fn1;
var reset = yield current;
if (reset) {
fn1 = 0;
fn2 = 1;
}
}
}
var sequence = fibonacci();
console.log(sequence.next().value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3
console.log(sequence.next().value); // 5
console.log(sequence.next().value); // 8
console.log(sequence.next(true).value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
I appreciate an elaborate text to answer the following questions together :
Why is reset
tested falsy after all those yield current
assigned to it?
that leads to a more general question:
How does yield
behave in assignment?
Where exactly does a value passed to next()
go?
because here in this code
function *createIterator() {
let first = yield 1;
let second = yield first + 2; // 4 + 2
yield second + 3; // 5 + 3
}
let iterator = createIterator();
console.log(iterator.next()); // "{ value: 1, done: false }"
console.log(iterator.next(4)); // "{ value: 6, done: false }"
console.log(iterator.next(5)); // "{ value: 8, done: false }"
console.log(iterator.next()); // "{ value: undefined, done: true }"
now I replace yield first + 2
by yield (first + 2)
and still got the same results. So what is the mechanics behind that?
A step by step detailed answer would be golden since I'm new to this programming style. I repeat for the speed readers: please help me understand how Javascipt execute such code instruction by instruction, thanks
When yields
is assigned it has two uses:
It determine each object returned by the next()
method of the iterator.
The trickiest part to understand is that the primary role of yield is performed here first (the right part of an assignment). then the generator code freezes. The next time next()
is called it resumes its execution. With first assigning the current next()
argument to the left part of the assignment.
Knowing that and that:
Each time the generator's next() method is called, the generator resumes execution and runs until it reaches one of the following:
A yield, which causes the generator to once again pause and return the generator's new value. The next time next() is called, execution resumes with the statement immediately after the yield. ...
Here's what execution of the second example looks like :
iterator.next()--->>>
yields 1
//next returns 1 in the 'value' property
//Freezing until the next call to next
iterator.next(4)--->>>
let first =4
yield first + 2;
//next returns 6 in the 'value' property
//Freezing until the next call to next
iterator.next(5)--->>>
let second = 5
yield second + 3;
// That is 8 in the value property
useful links :