This is how generator function works. First you have to invoke the generator function i.e GeneratorFunction which will give you iterator object.
var gen = GeneratorFunction(3);
When you invoke the next function of gen(returned iterator object) will returns an object which can contains 2 properties i.e value or done
The value property contains the value of the iteration and done tells us whether there is more value we can get from gen or not.
Example In the below snippet, when you invoke next method of iterator then it produces an object in which your value is in value property and done shows whether you can get more value from generator function or not.
After the done is true, All value will be undefined doesn't matter how many times you invoke the nextmethod
function* GeneratorFunction(i) {
yield 1;
yield 2;
yield 3;
}
var gen = GeneratorFunction(1);
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
NOTE: Most of the time you use generator function with for..of loop which will give you the value directly as
function* GeneratorFunction(i) {
yield 1;
yield 2;
yield 3;
}
var gen = GeneratorFunction(1);
for (let val of gen) {
console.log(val);
}
UPDATED: FUNCTION INVOCATION
When you invoke the generator function
var gen = GeneratorFunction(3);
It passes the value of i as 3 and the invocation of the Generator function starts until the first yield and generator function suspend and produces value as:
{ value: 3, done: false }
Since, the done is false so the generator function take charge and starts again with input value as 1 that will replace the yield and it is same as:
i += yield i; // same as i += 1;
and the value of i is now 4 which doesn't satisfy the condition of while loop and exits from the loop.
After that
return i;
which returns the object as
{ value: 4, done: true }
If a generator function returns a value, then the final call to next
returns an object that has both value and done defined. The value
property holds the return value of the generator function, and the
done property is true, indicating that there are no more value to
iterate.
After the done is true then the further invocation will return value as undefined and done as true.
I've changed snippet to simplify the returned value from the generator function as
function* GeneratorFunction(i) {
while (i < 4) {
i += yield i;
}
return "final value";
}
var gen = GeneratorFunction(3);
console.log(gen.next(1));
console.log(gen.next(1));
console.log(gen.next(1));
console.log(gen.next(1));
console.log(gen.next(1));
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }