Why is yield statement of a javascript generator function returning parameters of .next()?

Great question. I think reading the MDN on the .next() method is most helpful. You can define the value you want to pass within the generator function itself (i.e. yield 1) or pass the value via next() by saying something like gen.next(1)

The next() method itself returns an Object, with the properties value and a boolean done which signifies whether the generator function is complete (i.e. exhausted of available outputs and will now output only undefined for a value).

That said, there are two ways to access / pass it that value.

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


The confusion comes from the fact that yield and next have different syntaxes, while they actually do the same thing. Generator and its caller are symmetric (that's why they are called "co"-routines and not "sub"-routines). Both functions can be thought as connected by a communication channel, and can either do their job or sleep waiting for an incoming message in the channel. The only difference is that the generator is initially asleep (that is, there's an implicit "listen" command at the top of it), while the caller is initially awake.

Both yield and next do the same thing three things:

  • write its argument to the channel
  • fall asleep and listen for an incoming message
  • emit the incoming message as its value and wake up (that is, carry on with what's below them)

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 write comes before read, the very first message sent to the generator is lost. It's only used to wake up the generator. Also note how we've left the generator in the sleeping state, so the *** line is not reached.