David Gilbertson
David Gilbertson

Reputation: 4853

Why does the second yield return first in this generator

In the code below, why does the first call to next() return the value that comes after the second yield keyword?

function* generatorFunction() {
  yield (yield 'the second yield')();
}

function func(x) {
  return 'func passed to the second next()';
}

var iterator = generatorFunction();

var firstValue = iterator.next().value;
var secondValue = iterator.next(func).value;

console.log(firstValue); // "the second yield"
console.log(secondValue); // "func passed to the second next()"

On the first next() it treats the rest of the line after the first yield as an expression, right? Does that mean (yield x)() evaluates to x, but doesn't actually pause on the yield while it's evaluating it?

Then the second call to next passes in a function, does that function take the place of (yield 'the second yield') and so get executed and then return its value.

Can anyone help explain what's going on here?

BTW this serves no practical purpose, I'm just going through the es6katas.

Upvotes: 0

Views: 148

Answers (1)

Estus Flask
Estus Flask

Reputation: 222369

This is a good example but pretty much self-explaining.

The expression

yield (yield 'the second yield')();

is evaluated inside out, according to operator precedence.

First of all, right part of outer yield is evaluated, (yield 'the second yield')().

Left function part, (yield 'the second yield') group is evaluated first. 'the second yield' value is returned from first next() call, the generator is paused on inner yield.

The generator resumes on next(func) call, yield 'the second yield' is evaluated to sent value (func), then right function part func() is evaluated to 'func passed to the second next()'.

Finally, left part of outer yield is evaluated, 'func passed to the second next()' is returned from second next(func) call, the generator is paused.

Upvotes: 1

Related Questions