5

所以有一些方法可以在循环中停止生成器for of,但是如何break向生成器发送信号(与 in 相比returnfor-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." );
    }
}

它通过使用循环10次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()说一句,实现的 clear(it是主 Object 并获得了控制权,但是break?);

4

2 回答 2

4

像您的it生成器对象这样的可迭代对象具有一个带有键的属性,该键Symbol.iterator是一个返回迭代器的函数。迭代器需要有一种.next()方法从一个项目前进到下一个项目。Then 也可以选择有一个方法,当你、或.return()时调用该方法,导致在它运行完成之前停止。所以在你的情况下,会自动调用.breakreturnthrowfor..ofbreak;it.return()

另一方面是在 ES6 生成器上,.next()使其在当前暂停的 处恢复执行yield,并.return()使其行为类似于yieldisreturn语句,因此break在循环内部导致yield nextValue;行为类似于return;,这将退出生成器并触发finally块。

于 2017-02-22T00:25:07.777 回答
2

如何break向发生器发送信号?

循环将调用IteratorCloseoperation.return() ,如果迭代器对象具有这样的方法(生成器会这样做),这基本上相当于调用不带参数的迭代器方法。当评估循环体中的throwor语句时也会发生这种情况。return

顺便什么时候it.return()用,实现就清楚了

……但很可怕。正如您所发现的,它不会立即停止。那是因为方法调用只是推进生成器并从中获取一些结果,但与您的循环无关。循环体将继续执行,直到再次评估循环条件,然后检查迭代器并注意到它已经完成。

于 2017-02-22T00:25:36.743 回答