停止生成器时,Break如何在for-of循环中工作?

时间:2017-02-21 23:42:54

标签: javascript loops ecmascript-6 for-of-loop

因此,有一些方法可以在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

将其循环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是主要对象并且已获得控制权,但break怎么办?);

2 个答案:

答案 0 :(得分:4)

it生成器对象这样的可执行对象具有一个带有键Symbol.iterator的属性,它是一个返回迭代器的函数。迭代器必须使用.next()方法从一个项目前进到下一个项目。然后还可以选择使用.return()方法,该方法在breakreturnthrow时调用,导致for..of在运行之前停止完成。因此,在您的情况下,break;会自动调用it.return()

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

答案 1 :(得分:2)

  

break如何向发电机发送信号?

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

  

顺便使用it.return()时,实现很明确

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