2017-02-21 34 views
3

因此,有一些方法來for of循環停止發電機,但如何break(在for-of在比較return)發送一個信號發生器?停止發電機時,Break如何在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?);

+0

你正在擺脫for循環,你期望與'break'發生什麼? – pinkfloydx33

+0

不應該只寫「返回」;退出循環而不是「它。return(「stop」);「,你也在循環中使用break,它應該跳出循環。 –

+0

不完全確定你在問什麼 - 但Break用來跳出循環(並繼續任何方法在循環之外)返回將跳出一個方法,而不僅僅是一個循環 - 它可以返回一個值,Break不會返回一個值 – Korgrue

回答

1

break如何向發生器發送信號?

循環將調用IteratorClose operation,基本上相當於不帶任何參數,如果iterator對象有這樣一個方法調用迭代器的.return()方法 - 其中發電機做。 當評估循環體中的throwreturn語句時,也會發生這種情況。

it.return()使用的方式,實施明確

...但可怕的。正如你發現的那樣,它不會立即停止。這是因爲一個方法調用只會推動生成器,並從中獲得一些結果,但與循環無關。循環體將繼續執行,直到再次計算循環條件,然後檢查迭代器並注意它已完成。

2

像你的it生成器對象這樣的可重複對象有一個屬性,它的鍵Symbol.iterator是一個返回迭代器的函數。迭代器需要有一個.next()方法從一個項目前進到下一個項目。然後還可以選擇使用.return()方法,該方法在您執行breakreturnthrow時調用,導致for..of在其運行完成之前停止。所以在你的情況下,break;將自動調用it.return()

它的另一面是,在ES6發電機,.next()使得它在目前暫停yield恢復執行,並.return()使它像的yieldreturn語句,因此break內循環導致yield nextValue;表現得像return; ,它將退出發電機並觸發finally塊。

+0

我很欣賞它,你說在我的例子中'break'會自動調用'it.return()',但它只是把'{done:true}'這意味着我們避難我們剛剛告訴我們的迭代器它已經完成了。 因此,在調用'it.return()'之後'break'會終止它自己的循環迭代?(它做兩個工作對嗎?) –

+3

@MehdiRaash你是什麼意思通過「*但它只是把'{done:true}'*」?不,break會像循環一樣跳出循環,然後'for'將在繼續循環之後的下一條語句之前調用'it.return()'。 – Bergi

+0

是的,你永遠不會用'for..of'調用'it.return()'自己,就像你永遠不會自己調用'it.next()'一樣。在你的循環中放置一個「break」會爲你調用'.return'。 – loganfsmyth