Why does the yield statement of a javascript generator function return .next () parameters?

I came across generator functions on MDN , and that puzzles me with the following example:

function* logGenerator() { console.log(yield); console.log(yield); console.log(yield); } var gen = logGenerator(); // the first call of next executes from the start of the function // until the first yield statement gen.next(); gen.next('pretzel'); // pretzel gen.next('california'); // california gen.next('mayonnaise'); // mayonnaise 

I don’t understand why the yield , which is an argument to console.log , returns the parameter passed to the .next() method. Is this because an empty yield should return the value of the first parameter of the .next() method?

I also tried some more examples that seem to confirm the above statement:

 gen.next(1,2,3); // the printed value is 1, the 2 and 3 are ignored // and the actual yielded value is undefined 

Is there also a way to access additional parameters of the .next() method inside the body of the generator function?

Another thing I noticed is that while the yield statement returns these values ​​in console.log , they are not actually output as generator output. I have to say, I find this very confusing.

+5
source share
3 answers

Great question. I think that reading MDN using the .next() method is most useful. You can define the value that you want to pass inside the generator function itself (i.e. yield 1 ), or pass the value through next() by saying something like gen.next(1)

The next() operator itself returns an object with value and a boolean attached to it done to show whether the entire generator function has completed. And there are two ways to get / pass it to value .

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next

+2
source

The confusion arises from the fact that yield and next have different syntaxes, while they actually do the same thing. The generator and its caller are symmetrical (therefore, they are called "co" protons, not "sub" -routines). Both functions can be considered as connected by a communication channel and can either do their job or perform sleep mode, waiting for an incoming message in the channel. The only difference is that the generator is initially asleep (that is, there is an implicit β€œlisten” command at the top), while the caller woke up initially.

Both yield and next do the same thing three things:

  • write your argument to the channel
  • fall asleep and listen to an incoming message
  • emits an incoming message as its value and wakes up (that is, continues with what is lower)

Illustration:

 _ = console.log.bind(console) function *gen() { _('gen: good morning') _('gen: sending hi') _('gen: zzz') p = yield 'hi' _('gen: awake! got', p) _('gen: now sending fine') _('gen: zzz') p = yield 'fine' _('gen: awake! got', p) // *** } function main() { var g = gen() _('main: sending knock knock') _('main: zzz') r = g.next('knock knock') _('main: awake! got', r) _('main: sending how r u') _('main: zzz') r = g.next('how r u') _('main: awake! got', r) } main() 

Note that since the recording begins before reading, the first message sent to the generator is lost. It was used only to wake the generator. Also notice how we left the generator in sleep state, so line *** not reached.

+1
source

This makes it very clear:

[rv] = exit [expression];

expression Defines the value to return from the generator function through the iterator protocol. If omitted, undefined is returned instead.

rv Returns the optional value passed to the next () generator to resume execution.

Basically you print the parameter you sent to continue execution.

0
source

Source: https://habr.com/ru/post/1270902/


All Articles