停止生成器时,Break 如何在 for-of 循环中工作?
How does Break work in for-of loop when stopping a Generator?
所以有一些方法可以在for of
循环中停止一个生成器,但是break
如何向生成器发送信号(与return
在 for-of
)?
请考虑代码。
举个例子,前面的代码只是将一个值从 1 增加到 10,然后在中间执行 pause 和 resume。
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
:
循环 10 次
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
是主要的Object,已经拿到了控制权,但是break
呢?);
像您的 it
生成器对象这样的可迭代对象有一个带有键 Symbol.iterator
的 属性,它是一个返回迭代器的函数。迭代器需要有一个 .next()
方法来从一个项目前进到下一个。然后还可以选择有一个 .return()
方法,当你 break
、return
或 throw
时调用它,导致 for..of
在它运行到之前停止完成。所以在你的情况下,break;
会自动调用 it.return()
.
它的另一面是在 ES6 生成器上,.next()
使其在当前暂停的 yield
处恢复执行,而 .return()
使其表现得像 yield
是一个 return
语句,因此循环内的 break
导致 yield nextValue;
的行为类似于 return;
,这将退出生成器并触发 finally
块。
how does break
send a signal to the Generator?
循环将调用 IteratorClose
operation,这基本上相当于调用迭代器的 .return()
方法,如果迭代器对象有这样的方法——生成器有。
当评估循环体中的 throw
或 return
语句时也会发生这种情况。
When it.return()
is used by the way, the implementation is clear
……但是太可怕了。正如您所发现的,它不会立即停止。那是因为方法调用只是推进生成器并从中获取一些结果,但与循环无关。循环体将继续执行,直到再次评估循环条件,然后将检查迭代器并注意到它已经完成。
所以有一些方法可以在for of
循环中停止一个生成器,但是break
如何向生成器发送信号(与return
在 for-of
)?
请考虑代码。
举个例子,前面的代码只是将一个值从 1 增加到 10,然后在中间执行 pause 和 resume。
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
是主要的Object,已经拿到了控制权,但是break
呢?);
像您的 it
生成器对象这样的可迭代对象有一个带有键 Symbol.iterator
的 属性,它是一个返回迭代器的函数。迭代器需要有一个 .next()
方法来从一个项目前进到下一个。然后还可以选择有一个 .return()
方法,当你 break
、return
或 throw
时调用它,导致 for..of
在它运行到之前停止完成。所以在你的情况下,break;
会自动调用 it.return()
.
它的另一面是在 ES6 生成器上,.next()
使其在当前暂停的 yield
处恢复执行,而 .return()
使其表现得像 yield
是一个 return
语句,因此循环内的 break
导致 yield nextValue;
的行为类似于 return;
,这将退出生成器并触发 finally
块。
how does
break
send a signal to the Generator?
循环将调用 IteratorClose
operation,这基本上相当于调用迭代器的 .return()
方法,如果迭代器对象有这样的方法——生成器有。
当评估循环体中的 throw
或 return
语句时也会发生这种情况。
When
it.return()
is used by the way, the implementation is clear
……但是太可怕了。正如您所发现的,它不会立即停止。那是因为方法调用只是推进生成器并从中获取一些结果,但与循环无关。循环体将继续执行,直到再次评估循环条件,然后将检查迭代器并注意到它已经完成。