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

Javascript 为什么这个迭代器返回以下值?,javascript,ecmascript-6,generator,Javascript,Ecmascript 6,Generator,我正在阅读,看到了以下片段: 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 } c

我正在阅读,看到了以下片段:

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?不应该
它。接下来(12)
提供
收益率(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));
日志

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

只有对
.next(12)
的第二次调用(此处传入一个值)将恢复生成器代码,传入的值是
产生的
表达式的结果(然后乘以
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)
}

我理解对了吗?基本上,在调用第一个
it.next()
之后,6将返回给调用者,节点将以相同的速率挂起函数?因此,当调用
it.next(12)
时,它使用12,而不是x+1,对吗?@Geo:这就是
yield
的工作原理,是的:-)在大多数情况下(像迭代器一样),你不关心传入的值(或者根本不传入值),但你可以用它做一些有趣的事情。请阅读您在问题中链接的文章系列!
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)
}