为什么这个迭代器返回以下值?

Why is this iterator returning the following values?

我正在阅读 this article about javascript generators,我读到了以下片段:

function *foo(x) {
    var y = 2 * (yield (x + 1));
    var z = yield (y / 3);
    return (x + y + z);
}

var it = foo( 5 );

// note: not sending anything into `next()` here
console.log( it.next() );       // { value:6, done:false }
console.log( it.next( 12 ) );   // { value:8, done:false }
console.log( it.next( 13 ) );   // { value:42, done:true }

我不明白第一个 it.next() 的目的。执行完之后,这一行,迭代器不应该暂停在var z = yield (y / 3),y的值为6吗? it.next(12) 不应该为 yield (y / 3) 提供参数,然后 z 是 4 吗?我不明白为什么函数的结果不是 5 + 12 + 4。不知何故好像第一个 it.next() 被忽略了。是这样吗?有人可以解释一下吗?

您可能想要添加一些日志记录语句以查看发生了什么:

function *foo(x) {
    console.log("starting");
    var y = 2 * (yield (x + 1));
    console.log("y", y);
    var z = yield (y / 3);
    console.log("z", z);
    return (x + y + z);
}

var it = foo( 5 );
console.log("it", it);
console.log(it.next());
console.log(it.next(12));
console.log(it.next(13));

日志

it {next: …}
starting
{ value:6, done:false }
y 24
{ value:8, done:false }
z 13
{ value:42, done:true }

如您所见,调用 foo(5) 仅创建生成器对象,但尚未启动它。只有对 it.next() 的第一次调用会执行此操作,返回第一个 yield 的结果。第一次调用不接受任何参数,因为无论如何在生成器函数内部都无法访问它。

只有第二次调用 .next(12),这里传入一个值,然后会恢复生成器代码,传入的值是 yield 表达式的结果(然后乘以 2).

这可能会有所帮助

function *foo(x) {
    var y = 2 * (yield (x + 1)); 
       // x = 5 (from foo(5) ) so it yields 6
       // next(12) => var y = 2 * (12) == 24
    var z = yield (y / 3);
       // from above y = 24 so yields 8
       // next(13) => var z = 13    
    return (x + y + z);
       // 5 + 24 + 13 == 42 (and done: true)
}