ES6生成器 - 第一个next()没有yield表达式的示例

时间:2014-11-02 02:14:18

标签: javascript ecmascript-6 ecmascript-harmony

对于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),就像使用普通函数一样。

     

第一个下一个(..)电话,我们不发送任何内容。为什么?因为没有收益表达式来接收我们传递的东西。

1 个答案:

答案 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 / 3z的值分配给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}}