Javascript Generators问题-解释此代码

时间:2019-05-08 12:29:30

标签: javascript generator

我正在阅读Flavio Scopes撰写的“ JavaScript手册”。他介绍了生成器的概念。

function* calculator(input) {
  var doubleThat = 2 * (yield(input / 2))
  var another = yield(doubleThat)
  return (input * doubleThat * another)
}

// He then runs the following code

const calc = calculator(10)
console.log(calc.next())

输出

{value: 5, done: false}

calc.next(7);

输出:

{value: 14, done: false}

我理解第一个输出,但是我不理解第二个输出。为什么输出14?

我的理解是,下一次在.next()上调用calc时,它应该在之后行上最后一次暂停的行上继续。

好吧,这一行就是这一行:var another = yield(doubleThat),此时变量doubleThat的值应该是10,所以我期望第二个yield返回一个值为的对象10。

由于我了解生成器(Python)和迭代器(C ++ / Python)的概念,并且理解其他Javascript生成器示例,因此我认为书中的示例不是一个很好的示例。了解这里发生了什么。

谁能解释为什么calc.next(7)之后返回的值是14?

2 个答案:

答案 0 :(得分:4)

.next(7)的调用为第一个yield表达式提供了一个值,覆盖了先前计算并返回的值5。这是双向的关系。需要清楚的是,第一个yield“暂停”了中间表达式。执行将从该表达式内部继续,而不是下一条语句。

也就是说,我倾向于同意这是一个有问题的例子,因为我不确定这是现实的情况。很难想象像这样针对某些实际应用程序故意构建的代码。

答案 1 :(得分:3)

function* calculator(input) {
  var doubleThat = 2 * (yield(input / 2))
  var another = yield(doubleThat)
  return (input * doubleThat * another)
}

const calc = calculator(10)
console.log(calc.next()); 

到那时,您的第一个收益为10 / 2

然后

calc.next(7);

代码现在是这个

var doubleThat = 2 * (7) // yield expression transformed into 7

因此,值为14

您可以通过调试器获得一些见识

function* calculator(input) {
  var doubleThat = 2 * (yield(input / 2))
  var another = yield(doubleThat)
  return (input * doubleThat * another)
}

const calc = calculator(10)
debugger;
console.log(calc.next()); 
debugger;
console.log(calc.next(7))

唯一奇怪的是,当您输入第二行时,调试器使您进入函数的第二行,似乎没有执行2*7。我认为这似乎只是因为它不会停止中间表达,但我可能是错的。