-4

i am totally new to javascript in ES6 i know very basic about javascript

function *GeneratorFunction(i) { 
while (i < 4) { 
i += yield i; 
} 
return i;
}
var gen = GeneratorFunction(3);
console.log(gen.next(1));
console.log(gen.next(1));
console.log(gen.next(1));

output is below

{value: 3, done: false}// this is when statement is get true
{value: 4, done: true}// ? didn't get this point
{value: undefined, done: true}// ?
undefined //?

i dont know why output is in keyvalue pair. please answer "?" in outputs.

Farruk
  • 31
  • 1
  • 9
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators – ASDFGerte Sep 18 '21 at 13:15
  • For your second question, see https://stackoverflow.com/questions/14633968/chrome-firefox-console-log-always-appends-a-line-saying-undefined – Bergi Sep 18 '21 at 13:25

2 Answers2

1

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; }
DecPK
  • 24,537
  • 6
  • 26
  • 42
  • than why does my output is like this {value: 3, done: false}//if generator function have done false than why it becomes true in next line of output? and in 3rd line of output it is again true and value is undefine {value: 4, done: true} {value: undefined, done: true} – Farruk Sep 18 '21 at 14:28
  • Updated answer. Hope you will get what you were expecting... – DecPK Sep 18 '21 at 15:08
  • Lovely explanation thanks – Farruk Sep 19 '21 at 07:00
0

May be you can use console.log(gen.next().value) instead of console.log(gen.next(1)) for the output you want, which will prevent to get the output in key value pair.

Penn
  • 13
  • 2