dma*_*man 3 javascript ecmascript-harmony ecmascript-6
对于ES6生成器,为什么这篇博文的作者说:
来自: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 }
Run Code Online (Sandbox Code Playgroud)
您可以看到我们仍然可以使用初始foo(5)iterator-instantiation调用传递参数(在我们的示例中为x),就像使用普通函数一样.
第一个下一个(..)电话,我们不发送任何东西.为什么?因为没有收益表达式来接收我们传递的内容.
小智 6
第一个it.next()对应于yield(x + 1),其结果为预期的6.下一次调用中的12 it.next(12)将第一个yield的值设置为12,因此y将其设置为两倍,或24并且迭代器得到的值为(y / 3)8.最后调用it.next(13)将第二个yield的值设置为13,设置为z,并接收其值return,即5 + 24 + 13.
当然,由于语法原因,它有点令人困惑
z = yield(y / 3)
Run Code Online (Sandbox Code Playgroud)
这在某种程度上看起来像一个被分配的东西做的价值y / 3来z.事实并非如此.y / 3是作为迭代器的值而z被赋予的值,而被分配给由以下 it.next()调用传入的值,这是完全不同的东西!省略括号并将其写为可能略有帮助
var y = 2 * yield x + 1;
var z = yield y / 3;
Run Code Online (Sandbox Code Playgroud)
请记住,这yield是一个声明,而不是函数调用.
至于你提到的错误,例如在traceur中它是"发送给新生的发电机的价值".当你想到它时,它是有道理的.作为参数发送的值将it.next()成为生成器中最新产量的值.在第一次调用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";
}
};
}
Run Code Online (Sandbox Code Playgroud)
然后:
iterator = foo(5);
iterator(); // 6
iterator(12); // 8
iterator(13); // 42
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
352 次 |
| 最近记录: |