我正在阅读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?
答案 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
。我认为这似乎只是因为它不会停止中间表达,但我可能是错的。