对于ES6生成器,为什么this blog post的作者说:
来自:http://davidwalsh.name/es6-generators
"第一个下一个(..)电话,我们不发送任何内容。为什么?因为没有收益表达式来接收我们传递的内容。"
不是第一个it.next()
来电(yield (x + 1))
?
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 }
你可以看到我们仍然可以使用初始的foo(5)iterator-instantiation调用传递参数(在我们的例子中为x),就像使用普通函数一样。
第一个下一个(..)电话,我们不发送任何内容。为什么?因为没有收益表达式来接收我们传递的东西。
答案 0 :(得分:6)
第一个it.next()
对应yield(x + 1)
,按预期结果为6。下一次调用it.next(12)
时的12将第一个yield的值设置为12,因此将y
设置为加倍,或24,迭代器得到值(y / 3)
,是8.对it.next(13)
的最终调用将第二次收益的值设置为13,设置为z
,并获得return
的值,即5 + 24 + 13。
当然,由于语法
,它有点令人困惑z = yield(y / 3)
以某种方式看起来像是将y / 3
与z
的值分配给y / 3
。事实并非如此。 z
是用作迭代器值的值,而it.next()
被分配给跟随 var y = 2 * yield x + 1;
var z = yield y / 3;
调用传入的值,完全不同的东西!省略括号并将其写为
yield
请记住,it.next()
是一个语句,而不是函数调用。
至于你提到的错误,例如在traceur中它是"向新生的发生器发送值"。当你想到它时,它是有道理的。作为参数发送到it.next()
的值将成为生成器中最近产量的值。在第一次调用x
时, 在生成器中没有最近的收益,因此无法对传递的值采取任何措施,因此错误。
不要将传递参数混淆到生成器(在您的情况下为it.next()
),这仅提供配置或初始化生成器的方法,并将参数传递给yield
,其作用为生成器中最新{value, done}
的值。
考虑如何编写等效的手动轧制发电机(简化为仅返回下一个值而不是function foo(x) {
var y, z, step = 0;
return function next(val) {
switch (step++) {
case 0: return x + 1; break;
case 1: y = 2 * val; return y / 3; break;
case 2: z = val; return x + y + z; break;
default: throw "generator finished";
}
};
}
,并在发电机缺气时抛出)可能会有所帮助:
iterator = foo(5);
iterator(); // 6
iterator(12); // 8
iterator(13); // 42
然后:
{{1}}