带有next()调用的生成器函数

Generator functions with next() call

本文关键字:函数 调用 next 带有      更新时间:2024-06-24

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

在官方文件中,他们说,我引用:A zero arguments function that returns an object with two properties:,根据他们的网站在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),它将为a分配1,并输出{value: 2, done: false}

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

问题

  1. 如果官方文件中说它是一个零参数函数,那么你怎么可能用参数调用.next()
  2. 为什么在第三个结果中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. 
  1. 如果在官方文档中声明它是一个零参数函数,那么你怎么可能用参数调用.next()呢

引用ES-6的草案版本,

参数可以传递给next函数,但它们的解释和有效性取决于目标迭代器for-of语句和Iterator的其他常见用户不传递任何参数,因此期望以这种方式使用的Iterator对象必须准备好在没有参数的情况下进行调用。

因此,向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 }

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

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}