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

ES6 Generators- Example where there is no yield expression for the first next()

本文关键字:yield 没有 表达式 next 第一个 ES6      更新时间:2023-09-26

对于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 }

您可以看到,我们仍然可以通过初始的foo(5)迭代器实例化调用传递参数(在我们的示例中为x),就像使用普通函数一样。

下一个(..)的第一个电话,我们什么都不寄。为什么?因为没有收益率表达式来接收我们传入的内容。

第一个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)

这在某种程度上看起来像是将与CCD_ 11有关的某个值分配给CCD_。事实并非如此。y / 3是生成的值,用作迭代器的值,而z被分配给下面的it.next()调用传递的值,完全不同!省略括号并将其写为可能会有一些帮助

var y = 2 * yield x + 1;
var z = yield y / 3;

请记住,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";
        }
    };
}

然后:

iterator = foo(5);
iterator();             // 6
iterator(12);           // 8
iterator(13);           // 42