因此,有一些方法可以在for of
循环中停止生成器,但break
如何向生成器发送信号(与return
相比较在for-of
)?
请考虑代码。
例如,前面的代码只是将值从1增加到10,并在其间执行暂停和恢复。
function *Generator() {
try {
var nextValue;
while (true) {
if (nextValue === undefined) {
nextValue = 1;
}
else {
nextValue++;
}
yield nextValue;
}
}
// cleanup clause
finally {
console.log( "finally has been reached." );
}
}
使用for of
:
var it = Generator();// it gets Generator's iterator
for (var v of it) {
console.log(v);
if (v > 9) {
//it.return("stop");//this is another tool for stopping, but it doesn't stop immediately.
break;
console.log("it won't run");//this line won't run
}
}
顺便使用it.return()
时,实现清晰(it
是主要对象并且已获得控制权,但break
怎么办?);
答案 0 :(得分:4)
像it
生成器对象这样的可执行对象具有一个带有键Symbol.iterator
的属性,它是一个返回迭代器的函数。迭代器必须使用.next()
方法从一个项目前进到下一个项目。然后还可以选择使用.return()
方法,该方法在break
,return
或throw
时调用,导致for..of
在运行之前停止完成。因此,在您的情况下,break;
会自动调用it.return()
。
另一方面是在ES6生成器上,.next()
使其在当前暂停的yield
处恢复执行,.return()
使其像yield
一样行动一个return
语句,因此循环内break
导致yield nextValue;
的行为类似于return;
,它将退出生成器并触发finally
块。
答案 1 :(得分:2)
break
如何向发电机发送信号?
循环将调用IteratorClose
operation,这基本上相当于调用迭代器的.return()
方法而没有参数,如果迭代器对象具有这样的方法 - 生成器会这样做。
当评估循环体中的throw
或return
语句时,也会发生这种情况。
顺便使用
it.return()
时,实现很明确
......但太可怕了。如你所知,它不会立即停止。那是因为方法调用只是推进生成器并从中获取一些结果,但与循环无关。循环体将继续执行,直到再次评估循环条件,然后检查迭代器并注意它已经完成。