【问题标题】:How does Break work in for-of loop when stopping a Generator?停止生成器时,Break 在 for-of 循​​环中如何工作?
【发布时间】:2017-07-11 19:54:12
【问题描述】:

所以有一些方法可以在for of 循环中停止生成器,但是break 如何向生成器发送信号(与for-of 中的return 相比)?

请考虑代码。

例如,前面的代码只是将一个值从 1 增加到 10 ,并在其间执行 pauseresume

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呢?);

【问题讨论】:

  • 您正在跳出 for 循环,您希望 break 会发生什么?
  • 你不应该只写“return”吗?退出循环而不是"it.return("stop");",你也在循环中使用了break,它应该跳出循环。
  • 不完全确定你在问什么 - 但 Break 用于跳出循环(并继续循环外的任何方法)。 Return 将打破一个方法,而不仅仅是一个循环 - 它可以返回一个值。 Break 不返回值。
  • 好的,我会补充一些更清楚的问题。
  • 为什么要命名函数Generator

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


【解决方案1】:

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

另一方面是在 ES6 生成器上,.next() 使其在当前暂停的yield 处恢复执行,而.return() 使其表现得就像yield 是一个return 语句,所以@循环内的 987654336@ 导致 yield nextValue; 的行为类似于 return;,这将退出生成器并触发 finally 块。

【讨论】:

  • 我很感激,你说在我的情况下break 会自动调用it.return(),但它只是把{done: true} 这意味着我们实际上并没有打破for-of 循环体,我们只是告诉我们的迭代器它已经完成了。那么break 在调用it.return() 之后会终止它自己的循环迭代吗? (它做两件事对吗?)
  • @MehdiRaash “但它只是放了{done: true}”是什么意思?不,break 像往常一样跳出循环,然后for 将调用it.return(),然后继续循环后的下一条语句。
  • 是的,你永远不会用for..of 自己打电话给it.return(),就像你永远不会自己打电话给it.next()。将break 放入循环中将为您调用.return
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-23
    • 2021-07-15
    • 1970-01-01
    • 2022-01-11
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    相关资源
    最近更新 更多