MDN建议“调用迭代器的next()方法时,将生成器函数的主体直到执行,直到第一个yield表达式为止”,我确实理解了以下示例:
function* logGenerator() {
console.log(0);
console.log(1, yield);
console.log(2, yield);
console.log(3, yield);
}
var gen = logGenerator();
gen.next(); // 0
gen.next('pretzel'); // 1 pretzel
gen.next('california'); // 2 california
gen.next('mayonnaise'); // 3 mayonnaise
但是,当我遇到另一个例子时,我很困惑:
const foo = function*() {
yield 10;
yield 20;
};
const bar = foo();
console.log(bar.next()); // {value: 10, done: false}
如果第一个next()
仅在第一个收益率之前执行代码之前,则该值应未定义。如何获得第一笔收益 WITHIN 的价值?我在这里有点困惑。感谢您的帮助。
答案 0 :(得分:3)
您可以通过记录生成器每次生成的结果以及向yield
表达式中添加值来查看发生了什么,并且可以看到生成器实际生成的结果(MDN示例不打扰这样做是因为它从未使用过产生的值,而只是演示了next()
参数的工作方式。)
通常,您不会使用单个生成器来生成值,也不会通过next()
参数来接收值,而仅使用一个生成器。如果产生值,则可以单独使用yield <expression>
作为语句(类似于return
),而不是通常在表达式中使用。如果它接收到值,则可以在表达式中不带参数的情况下使用yield
。但是,正如您在修改后的示例中看到的那样,底层机制同时允许两者。您只需要跟踪混乱的执行顺序即可。
function* logGenerator() {
console.log(0);
console.log(1, yield 10);
console.log(2, yield 20);
console.log(3, yield 30);
}
var gen = logGenerator();
console.log("call 1 yielded", gen.next().value); // 0
console.log("call 2 yielded", gen.next('pretzel').value); // 1 pretzel
console.log("call 3 yielded", gen.next('california').value); // 2 california
console.log("call 4 yielded", gen.next('mayonnaise').value); // 3 mayonnaise
您第一次调用生成器是执行console.log(0);
,然后开始执行console.log(1, yield 10)
。但是当到达yield
表达式时,next()
会在实际调用console.log()
的之前返回该值。
下次调用生成器时,它将在中断处恢复,这将构造console.log()
的参数。 yield 10
表达式被next()
的参数替换,因此它执行console.log(1, 'pretzel')
。
然后它开始执行console.log(2, yield 20)
,并且发生同样的事情-在调用20
之前产生console.log()
。
MDN试图显示的是next()
的参数仅在第二次调用时才有意义,因为当生成器恢复时,它会替换中断表达式中的yield
的值。第一次调用时使用参数无效,因为没有可替换的中断表达式。