我试图了解如何使用ES6 Generator功能。除了这个关于在传递参数时进行空的next()函数调用的概念时,它似乎非常简单。这是我从Mozilla文档中引用的代码。
function* logGenerator() {
console.log(yield);
console.log(yield);
console.log(yield);
}
var gen = logGenerator();
// the first call of next executes from the start of the function
// until the first yield statement
gen.next();
gen.next('pretzel'); // pretzel
gen.next('california'); // california
gen.next('mayonnaise'); // mayonnaise
根据我的理解,代码只执行到第一个yield语句,因此没有返回任何内容,然后第二次调用next()
,代码执行到包含第一个yield行的第二个yield因此pretzel
被记录到控制台。
如果是这种情况,在下面提到的代码中,0
如何在next()
的第一次调用中登录?我在这里遗漏了一些东西:(
function* idMaker() {
var index = 0;
while (index < 3)
yield index++;
}
var gen = idMaker();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // undefined
答案 0 :(得分:6)
嗯,发电机功能很特别。它们可以在执行过程中多次接受和返回值,而“普通”函数只能接受一组固定的参数,并返回单个值。在您的第一个示例中,它们用于将数据传递给生成器(多次传递参数),而在第二个示例中则反过来(多次返回值)。
考虑这个例子:
function* foo() {
console.log("before a");
var a = (yield 123);
console.log("after a");
yield (a * 2);
console.log("end of function");
}
var bar = foo();
var x = bar.next(); // Runs until the first yield, prints 'before a'.
console.log(x.value); // 123
var y = bar.next(4); // Runs until the second yield, so prints 'after a'.
console.log(y.value); // 8
var z = bar.next(); // prints 'end of function'.
console.log(z.done); // true
我们没有传递第一个next()
调用的数据,让它一直运行到第一个yield
语句。由于yield 123
,调用的结果(x.value
)为123.下次我们使用next()
作为参数值调用4
时,我们会填充局部变量{{1} }在生成器函数内部。代码执行到下一个a
语句并返回yield
的结果。
有关8
代替0
的解释,请参阅另一个答案。
答案 1 :(得分:3)
我认为你遇到的是后增量运算符的行为,即index++
。如果您将其更改为预增量运算符,即++index
,它将按照您期望的方式运行。
不同之处在于,在评估表达式之后,后递增将向index
添加1。在评估表达式之前,预增量将向index
添加1,我认为这是您的目标。
答案 2 :(得分:0)
根据我的理解,代码只执行到第一个yield语句,因此不返回任何内容
在Mozilla的例子中,&#34;产生&#34;所有返回SOMETHING,他们返回undefined。这就像是&#34;返回&#34;在它之后没有任何东西,这也&#34;返回&#34;未定义。
这里特别的是,因为这是一个生成器函数,所以返回/收益发生在log()-statement的MIDDLE中。它们会在&#34;产生&#34; -statement STARTS EXECUTING。这意味着他们会跳出来#34;当前函数在log()语句完成之前,因此在第一次调用时没有任何内容到达控制台。换句话说,第一次收益导致函数*跳出&#34;跳出&#34;在log-statement获得执行机会之前。
当你打电话给第二个next()时,执行会从上次停止的时间开始继续执行,但是使用术语&#39; yield&#39;现在是作为参数传递给next()的东西。因此,log-statement现在继续并打印该值。
获得收益的棘手部分是这个&#34;瞬间&#34;冻结和下一个下一个()从上一次冻结的完全相同的点继续但是与术语“屈服”相对应。现在具有作为参数传递给next()的值。如果在某些语句(如log(yield))内发生yield,则冻结在contains语句能够执行之前发生。
或者换句话说,我觉得棘手的部分(而且我为什么重复自己这很棘手)是yield-statement导致函数在yield-statement完成之前返回。它将仅在下一个next()上完成,具有&#34; yield&#34;的值。变成对next()的调用的参数。
你的例子的不同之处在于你的log()-statements都发生在生成器函数的外面,在Mozilla的例子中它们发生在它里面。因此,您的logs()将使用从next()调用获得的值执行。由于您的logs()发生在生成器之外,因此您的所有log()语句都不会在中间被中断。