2016-11-07 72 views
1

我試圖理解發生器,但我發現了一個我不能遵循的例子。迭代發生器返回一個發生器

// First Generator 
 

 
function* Colors() 
 
{ 
 
    yield "blue"; 
 
    yield* MoreColors(); 
 
    yield "green"; 
 
} 
 

 
// Generator refered by the first Generator 
 
function* MoreColors() 
 
{ 
 
    yield "yellow"; 
 
    yield "orange"; 
 
} 
 

 

 
// Let us iterate over the first Generator 
 

 
const colorIterator = Colors(); 
 

 
let color; 
 

 
while (!(color = colorIterator.next()).done) 
 
{ 
 
    console.log(color.value); 
 
}

輸出是: 「藍色」 「黃」 「橙」 「綠色」

我預計: 「藍色」 「黃色「 」橙色「

爲什麼我預計: 我認爲橙色已經返回後,該方法的.next()是呼籲迭代器MoreColors()。這應該返回一個對象,其物理值爲true爲物業.done。 由此,項目等於true並且while循環應停止。

顯然,我的期望是錯誤的。

我會很高興,如果有人能指出我錯了什麼。

+2

'yield *'如果沒有fixup'done'屬性就沒用了;這意味着外部生成器報告在第一個委託生成器結束後立即完成。 – ShadowRanger

回答

1

問題是發生器顏色不停止一旦MoreColors停止。 MoreColors完成後,顏色的執行將從其停止的位置開始繼續執行,因此在完成之前它會返回「綠色」。這是因爲生成器不會「變成」MoreColors,而是返回它的答案,並且仍然在Colors上調用.next()方法。

+0

感謝您的快速響應!但從技術上講,我仍然不明白髮生了什麼事。我是否正確理解你的答案,發生器顏色本身是負責的,while循環是否會被進一步執行? – Jim

+0

是的。當你使用yield *,並且你應用它的生成器(MoreColors)返回{done:true}時,原始生成器(Colors)檢測到並且不是返回該值,而是繼續執行,直到它到達另一個yield語句或完成它執行 – matanso

+1

matanso和@ShadowRanger:非常感謝您分享您的知識!你幫了我很多! – Jim