【问题标题】:Generator functions with next() call带有 next() 调用的生成器函数
【发布时间】:2015-02-26 13:29:46
【问题描述】:

我从 ecmascript 6 看到了新的未来 - 生成器函数,我对 .next() 函数的作用有点困惑。

在他们说的官方文档中,我引用了:A zero arguments function that returns an object with two properties:,根据他们的website 更新了Feb 17, 2015 4:57:46 PM 上的信息(<- 链接到此处提供的文档)

所以,假设我们有这个生成器函数:

 function* first(){
    yield 1;
    yield 2;
 }
 var f= first();

调用f.next() 时将返回{value:1, done:false}。当你再次调用它时会返回{value:2, done:true}

但是,如果我们有这样的事情:

function* second() {
  var a = yield "HELLO";
  console.log("a = ", a);

  var b = yield a+ 1;
  console.log("b = ", b);

  return b
}
var f= second();

当你这样称呼它时:f.next()你会收到{value: "HELLO", done: false}

下一个调用将是f.next(1),它会将1分配给a,它会输出{value: 2, done: false}

下一个调用将是f.next(1),它将输出{value: 1, done: true}

问题

  1. 如果在官方文档中声明它是一个零参数函数,你怎么可能用参数调用.next()
  2. 为什么在第 3 个结果中,value 属性等于 1,而在第二个调用中,它等于 2?
  3. 为什么 b 是 1 而不是 2?

谢谢!

PS: Of course, there's another usage of generator functions ( to avoid callbacks ), but I'm asking about this particular case. 

【问题讨论】:

  • 虽然 MDN 是 JavaScript 的一个很好的来源,但你不能说它是“官方”文档。真正正式的只有 ECMAScript 规范。
  • 我不知道。我从上面的那个人那里得到了一个链接。谢谢!

标签: javascript ecmascript-6


【解决方案1】:
  1. 如果在官方文档中声明它是一个零参数函数,你怎么可能用参数调用 .next() ?

引用draft version of ES-6

参数可以传递给next 函数,但它们的解释和有效性取决于目标迭代器。 for-of 语句和迭代器的其他普通用户不传递任何参数,因此期望以这种方式使用的迭代器对象必须准备好处理不带参数的调用。

因此,将参数传递给next 并不违反 ES6 规范。在这种情况下,传递给next 的值将被分配给您将yield 表达式分配给的变量。

  1. 为什么在第三个结果的 value 属性等于 1 而在第二个调用它等于 2?
  2. 为什么 b 是 1 而不是 2?

按发生顺序排列的操作列表

  1. f.next()

    yield "HELLO"
    

    所以你得到{ value: 'HELLO', done: false }

  2. f.next(1)

    var a = 1;
    console.log("a = ", a);
    yield a + 1
    

    这就是您在此通话中收到{ value: 2, done: false } 的原因。

  3. f.next(1)

    var b = 1;
    console.log("b = ", b);
    return b
    

    这就是为什么你在这里得到{ value: 1, done: true }

【讨论】:

  • 是的,但是 var b= yield a +1 ?不应该是 2 吗?
  • @Kosmo 我稍微编辑了我的答案,它回答了你的问题吗?
  • 是的!谢谢 !我现在更好地理解了这个概念
【解决方案2】:

使用其他值,它会变得更加清晰。它按预期工作。

function* second() {
  var a = yield "HELLO";

  console.log("a = ", a);
  var b = yield a+ 1;

  console.log("b = ", b);
  return b
}
var f= second();

console.log('1:',f.next());
console.log('2:',f.next(5));
console.log('3:',f.next(7));

输出

///1st next()
//yeld returns iterator
{value: "HELLO", done: false}

//2nd next(5)
//the console log gets executed with var a = 5
a = 5
//yeld returns iterator
{value: 6, done: false}

//3rd next(7)
//the console log gets executed with var b = 7
b = 7
//it doesn't use the 'a' var at all, neither does it add +1 to the yeld allocation
//yeld returns iterator
{value: 7, done: true}

【讨论】:

    猜你喜欢
    • 2018-11-07
    • 1970-01-01
    • 2015-05-12
    • 2012-08-29
    • 2021-01-16
    • 2017-02-05
    • 1970-01-01
    • 2017-08-29
    • 2019-10-17
    相关资源
    最近更新 更多