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

Generator functions with next() call

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

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

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

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

当调用 f.next() 时将 return {value:1, done:false}。当你再次调用它时将 return {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. 
  1. How it's possible you can call .next() with parameter if in the official documentations it's stated it's a zero parameter function ?

引用 draft version of ES-6,

Arguments may be passed to the next function but their interpretation and validity is dependent upon the target Iterator. The for-of statement and other common users of Iterators do not pass any arguments, so Iterator objects that expect to be used in such a manner must be prepared to deal with being called with no arguments.

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

  1. Why at 3rd result has value property equal to 1 and at the second call it's equal to 2?
  2. Why b is 1 and not 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}