【问题标题】:ES6 Generators- Example where there is no yield expression for the first next()ES6 Generators - 第一个 next() 没有 yield 表达式的示例
【发布时间】:2014-12-28 23:51:12
【问题描述】:

对于 ES6 生成器,为什么this blog post 的作者说:

来自:http://davidwalsh.name/es6-generators

“第一次 next(..) 调用,我们没有发送任何东西。为什么?因为没有 yield 表达式来接收我们传入的内容。”

不是第一个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),就像使用普通函数一样。

第一个 next(..) 调用,我们不发送任何东西。为什么?因为没有 yield 表达式来接收我们传入的内容。

【问题讨论】:

    标签: javascript ecmascript-6 ecmascript-harmony


    【解决方案1】:

    第一个it.next() 对应yield(x + 1),结果如预期的那样为6。下一次调用 it.next(12) 中的 12 将第一个 yield 的值设置为 12,因此将 y 设置为两倍,即 24,并且迭代器产生值 (y / 3),即 8。最后一次调用toit.next(13)将第二个yield的值设置为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 是一个语句,而不是函数调用。

    至于您提到的错误,例如在 traceur 中它是“向新生生成器发送值”。当你考虑它时,它是有道理的。作为参数发送到it.next() 的值成为生成器中最近产量的值。在第一次调用 it.next() 时,没有生成器中没有最近的 yield,所以没有什么可以接受传递的值,因此出现了错误。

    不要混淆将参数传递给生成器(在你的情况下为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
    

    【讨论】:

      猜你喜欢
      • 2019-04-04
      • 2014-01-25
      • 1970-01-01
      • 2017-02-05
      • 2015-12-11
      • 2021-12-11
      • 2014-06-26
      • 2013-12-07
      • 2018-06-09
      相关资源
      最近更新 更多