为什么JavaScript中的生成器函数在任何yield表达式之前停止?

时间:2019-01-01 19:06:10

标签: javascript

代码:

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');

输出:

0
mark
1 beta

但是,为什么不呢?

0
1 alpha
mark
2 beta

在此行:gen.next('alpha'); 该代码仅记录'0'并停止,但未达到第一个yield表达式,而实际应为'0\n1 alpha'。

并且永远不会记录“ alpha”。

1 个答案:

答案 0 :(得分:4)

您对发电机停止的位置了解不正确。公平地说,这是生成器最令人困惑的方面之一。生成器在碰到yield时立即停止,即使它位于表达式的中间。

在您的示例中:

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

您永远不会进入console.log(),因为它在评估参数时会影响良率。它将继续并在下一个log上完成next()。这就是为什么如果生成器要依赖传入的值,则生成器通常会被初始next()调用“预备”。next()的第一次调用无法传递值。

这是一个显示问题的简单示例:

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)