Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Generator.next() processes its parameter?

The documentation says that "You can also provide a parameter to the next method to send a value to the generator." Where does it sends it to?

For example, take these 3 generators:

function* one() {
  while(true) {
    var value = yield null;
  }
}
var g1 = one();  g1.next();
g1.next(1000); //yields null

function* two() {
  var i = 0;
  while (true) {
    i += yield i;
  }
}
var g2 = two(); g2.next(); 
g2.next(1000) // yields 1000

function* three(){
  var index = 0;
  while (true)
    yield index++;
}

 g3 = three();
 g3.next();
 g3.next(1000); // yields 1

In generators 3 and 1, the argument passed has no effect on next. Why is that? How does generator 2 calculates its return value? Why it is affected by the given argument?

like image 947
Federico Avatar asked May 20 '16 19:05

Federico


People also ask

What does next () do in JavaScript?

next() method is an inbuilt method in JavaScript which is used to return an object with two properties done and value.

How does a generator work?

Generator functions provide a powerful alternative: they allow you to define an iterative algorithm by writing a single function whose execution is not continuous. Generator functions are written using the function* syntax. When called, generator functions do not initially execute their code.

How does JavaScript generator work?

In JavaScript, generators provide a new way to work with functions and iterators. Using a generator, you can stop the execution of a function from anywhere inside the function. and continue executing code from a halted position.

Which is the correct way to declare a generator function?

The function* declaration ( function keyword followed by an asterisk) defines a generator function, which returns a Generator object.


2 Answers

The key to understanding this is knowing how the next function retrieves the argument passed to next(), which is as the return value of the yield operator:

[rv] = yield [expression];

Independently of the value of [expression], yield will assign to rv the value passed to next().

But, here comes the tricky part: yield will only assign the value passed to next() when resuming execution from a previous iteration. As a consequence, on the first iteration, yield does not assign anything to rv.

For example, if I have this generator:

function* gen() {
  // On the first iteration, yield does not return anything.
  //because it returns something ONLY when execution is resumed
  returnedFromYield = yield 'foo'; 
  yield returnedFromYield; 
}

returnedFromYield is undefined on the first iteration. When execution is resumed on the second iteration, yield assigns the passed value to the returnedFromYield variable, which is then returned:

g.next(1); // 'foo'
g.next(2); // 2

Let's review another example:

function* gen() {
  yield yield yield 5;
}

On the first iteration, (g.next()), yield will return 5, on the second iteration, (g.next(10)) yield is going to pass 10 to the second yield. That is, yield yield yield 5; on the second iteration is equivalent to yield yield 10;, and, on the third iteration, it's equivalent to yield valuePassedToNext.

like image 172
Federico Avatar answered Oct 13 '22 01:10

Federico


Here's an annotated example showing the logical flow and scope for the values passed to a generator's next method. The affected area of the next method call is highlighted in the corresponding color.

enter image description here

a: There is no yield, so argument 'one' is ignored. The generator pauses on line 5, returning the value 1.

b: Execution resumes and 'two' replaces yield on line 5, and is assigned to the yieldValue variable. Line 6 is executed. The generator pauses on line 8, returning the value 2.

c: Execution resumes and 'three' replaces yield on line 8, and is assigned to the yieldValue variable. Line 9 is executed. The generator pauses on line 11, returning the value 3.

d: Execution resumes and 'four' replaces yield on line 11, and is assigned to the yieldValue variable. Line 12 is executed. Line 14 is executed. Finally the generator is now done, returning the value undefined.

See the logs on line 28-36

like image 31
Christopher Reece Avatar answered Oct 13 '22 01:10

Christopher Reece