【问题标题】:Semantics of return value of a generator生成器返回值的语义
【发布时间】:2018-05-02 23:12:30
【问题描述】:

我在理解生成器中“返回”的语义时遇到了问题。我把它理解为最终的,因此也是最后的价值。

function* gen() {
  yield "foo";
  return "bar";
}

for (const x of gen()) {
  console.log(x);
}

这个例子只打印“foo”而不是“bar”。

编辑:

有没有办法用“for”语法获取“done=true”迭代器的返回值,还是总是会丢失?

【问题讨论】:

    标签: javascript typescript


    【解决方案1】:

    yield 关键字用于暂停和恢复生成器函数。

    function* gen() {
        yield "foo";
        yield "bar";
    }
    
    for (const x of gen()) {
        console.log(x);
    }
    

    它打印foobar。如果您想了解更多关于yield的详细信息,请点击here

    【讨论】:

      【解决方案2】:

      不,您无法从for … of 循环中获取返回值。不过你可以试试

      function* gen() {
        yield 1;
        yield 2;
        return "done";
      }
      function* genAndLogResult() {
        const val = yield* gen();
        console.log(val);
      }
      
      for (const x of genAndLogResult()) {
        console.log(x + 40);
      }
      

      【讨论】:

      • 不能yield yield* gen() 吗?
      • @JonasW。一个可以,但我不会推荐它。返回值通常与产生的值非常不同,它不是集合的一部分。如果gen 的作者没有把它放在那里,他可能有一个很好的理由。我用一个更好的例子更新了答案。
      • 我不认为这是正确的编程......这只是一个黑客。您不应该在任何算法中使用适当的语言来使用它。
      【解决方案3】:

      发件人:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function%2A

      生成器中的 return 语句在执行时将使生成器完成。如果返回一个值,它将作为值传回。已返回的生成器将不再产生任何值。

      for 循环跳过“完成”步骤是有道理的。例如:

      function* gen() { yield "foo" }
      const inst = gen()
      inst.next() // { done: false, value: "foo" }
      inst.next() // { done: true, value: undefined }
      
      function* gen() { yield "foo"; return "bar" }
      const inst = gen()
      inst.next() // { done: false, value: "foo" }
      inst.next() // { done: true, value: "bar" }
      

      由于生成器不一定有 return 语句,因此您不希望 for 循环的最后一次迭代总是必须处理最终的 undefined 值。

      【讨论】:

        猜你喜欢
        • 2016-06-02
        • 2021-12-14
        • 2021-01-16
        • 2016-10-06
        • 1970-01-01
        • 2012-07-02
        • 2013-12-25
        • 2021-12-29
        • 2020-09-22
        相关资源
        最近更新 更多