PranshuKhandal
PranshuKhandal

Reputation: 879

Why this generator function in JavaScript is stopping before any yield expression?

Code:

function* logGenerator() {
    console.log(0);
    console.log(1, yield);
    console.log(2, yield);
    console.log(3, yield);
}

var gen = logGenerator();
gen.next('alpha');
console.log('mark');
gen.next('beta');

Output:

0
mark
1 beta

but, why not:

0
1 alpha
mark
2 beta

In the line: gen.next('alpha'); the code only logs '0' and stops but does not reach the first yield expression, while the actual should have been '0\n1 alpha'.

And 'alpha' is never logged.

Upvotes: 2

Views: 419

Answers (1)

Mark
Mark

Reputation: 92481

You're understanding of where the generator stops is not correct. To be fair, it's one of the most confusing aspects of generators. A generator stops immediately when it hits yield even if that's in the middle of an expression.

So in your example:

console.log(0);        // logs 0
console.log(1, yield); // evaluates the parameters to console.log, sees yield and stops before running console.log

You never make it to the console.log() because it hits yield while evaluating the parameters. It will continue and finish the log on the next next(). This is why generators are often "primed" with an initial next() call if they are going to depend on values passed in. The first call of next() can't pass a value.

Here's a simpler example showing the issue:

let test = "start"

function* logGenerator() {
  console.log("genertator starting")
  test = yield
}

var gen = logGenerator();
// call initial next. `val1` is lost to priming the generator
gen.next('val1');

// the generator stops before the assignment to test
// test is still "start"
console.log(test)

// only on the second call can you get a value to test
gen.next('val2');
console.log(test)

Upvotes: 4

Related Questions