ES6生成器:.next()的输入值

ES6 Generators: input value for .next()

本文关键字:输入 next ES6      更新时间:2023-09-26

我关注这个很棒的博客,这里有一个生成器发送.next()方法值的简单示例:

var answers = [
  `It is certain`, `It is decidedly so`, `Without a doubt`,
  `Yes definitely`, `You may rely on it`, `As I see it, yes`,
  `Most likely`, `Outlook good`, `Yes`, `Signs point to yes`,
  `Reply hazy try again`, `Ask again later`, `Better not tell you now`,
  `Cannot predict now`, `Concentrate and ask again`,
  `Don't count on it`, `My reply is no`, `My sources say no`,
  `Outlook not so good`, `Very doubtful`
]
function answer () {
  return answers[Math.floor(Math.random() * answers.length)]
}
// The most relevant part
function* chat () {
  while (true) {
    let question = yield '[Genie] ' + answer()
    console.log(question)
  }
}

我真的不明白这个输入将如何产生这个输出:

var g = chat()
g.next()
console.log(g.next('[Me] Will ES6 die a painful death?').value)
// <- '[Me] Will ES6 die a painful death?'
// <- '[Genie] My sources say no'

第一个输出来自哪里——结果的[Me]部分?

yield之后的表达式将熄灭(返回)。传递给next()的值进入,yield表达式计算为该值。请注意,在第一个.next()调用中传递的任何值都会被丢弃而不使用。

  1. g.next()被称为

    let question = yield '[Genie] ' + answer()    
                         ^-------------------^
          execution is paused here, this expression is evaluated
          and the result will go out(returned)
               {value:"[Genie] ...",done:false}
    
  2. g.next('[Me] Will ES6 die a painful death?')称为

    g.next('[Me] Will ES6 die a painful death?').value
           ^----------------------------------^
     string goes in, execution continues, yield expression 
          will be evaluated as the passed in string
     let question = yield '[Genie] ' + answer(); //becomes -v
     let question = '[Me] Will ES6 die a painful death?';
    
  3. question等于[Me]字符串

  4. question通过console.log(question)登录到控制台
  5. 继续执行,直到遇到下一个产量

    let question = yield '[Genie] ' + answer()    
                         ^-------------------^
          execution is paused here, this expression is evaluated
          and the result will go out(returned)
               {value:"[Genie] ...",done:false}
    
  6. 现在g.next('[Me] Will ES6 die a painful death?')评估为

    {value:"[Genie] ...",done:false}
    

    最后一行评估如下:

    console.log( g.next('[Me] Will ES6 die a painful death?').value );
    //becomes 
    console.log( ({value:"[Genie] ...",done:false}).value );
    //which becomes
    console.log("[Genie] ...");
    

让我消除了很多困惑的是关于收益的MDN文档。

语法

[rv] = yield [expression];

rv

返回传递给生成器的next()方法以继续执行的可选值。

这就是为什么对next第二次调用将决定let question的值。这就是我们继续执行的地方。

生成器然后打印出问题,继续下一轮循环,得出下一个精灵的答案并停止。如果还有另一个对next的调用,则传递给它的参数将确定let question的下一个值。