【问题标题】:Javascript yield from the function nested inside generator嵌套在生成器中的函数产生的 Javascript
【发布时间】:2015-12-05 11:18:01
【问题描述】:

此代码生成错误:

function *giveNumbers() {
    [1, 2, 3].forEach(function(item) {
        yield item;
    })
}

这可能是因为 yield 在一个不是生成器的函数内部。有没有一种优雅的方法来克服这个问题?我的意思是:

function *giveNumbers() {
    let list = [1, 2, 3];
    for (let i = 0; i < list.length; i++) {
        yield list[i];
    }
}

【问题讨论】:

    标签: javascript node.js ecmascript-6


    【解决方案1】:

    这可能是因为 yield 在一个不是生成器的函数中。

    是的。您不能在回调中使用yield

    有没有优雅的方法来克服这个问题?

    取决于用例。通常,实际上想要从回调中yield 的理由为零。

    在您的情况下,您需要一个 for…of 循环,它优于 .forEach in almost every aspect 反正:

    function *giveNumbers() {
        for (let item of [1, 2, 3])
            yield item;
    }
    

    【讨论】:

    • Ceterum censeo forEach delendam esse a ES6.
    • 对于那些不懂拉丁语(比如我)或者懒得谷歌翻译的人:“forEach 肯定会在 ES6 中被淘汰”。
    • @Palisand Furthermore, I consider forEach 必须(应该)从 ES6 中删除
    • @Palisand 诚然,这至少是我的意思,我的拉丁文有点生疏,我不知道“a ES6”是否是正确的选择
    • @Bergi - “实际上想要从回调中产生的理由为零” - 原因是使异步代码同步。为什么?为了让它看起来更好。是否有一些绕过来实现这一点?
    【解决方案2】:

    您可以使用yield * 语法。

    function *giveNumbers() {
        yield * [1, 2, 3].map(function(item) {
            return item;
        })
    }
    

    【讨论】:

    • 这不会屈服于父范围
    【解决方案3】:

    yield 将结果返回给调用者。
    让我们假设 forEach 回调是一个生成器(在那里设置服装生成器不是问题) - 这意味着当回调 yield 得到结果时 - 它会将其返回给 forEach

    基本上,在您的问题中,您尝试做的是:

    callback -> yields to forEach -> yields to giveNumbers -> yields to caller
    

    所以,forEach 应该将结果返回给giveNumbers。但是由于forEach 不能这样工作,所以如果没有使用服装forEach 重新设计数组是不可能的。

    实际上,你第二个 sn-p 最优雅的开始。

    【讨论】:

      【解决方案4】:

      您也可以使用 while 并传递参数 (Demo)

      function *giveNumbers(array, start) {
          var index = start || 0;
          while(array.length > index + 1) {
              yield array[index++];
          }
          return array[index];
      }
      
      
      var g = giveNumbers([1,2,3], 0);
      
      var finished = false;
      
      while(!finished) {
          var next = g.next();
          console.log(next.value);
          if(next.done) {
              finished = true;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-06-27
        • 2011-02-03
        • 2017-03-06
        • 2016-08-21
        • 1970-01-01
        • 2017-09-29
        • 1970-01-01
        • 2011-09-19
        • 2017-02-16
        相关资源
        最近更新 更多