2017-11-11 155 views
0

我想寫一個函數,可以採取列表或生成器作爲輸入。例如,該功能:如何在for循環中重用ES6 javascript中的生成器?

function x(l) { 
    for (let i of l) { 
     console.log(i); 
    } 
    for (let i of l) { 
     console.log(i); 
    } 
} 

如果我運行這樣的:

x([1,2,3]) 

它會顯示:

1 
2 
3 
1 
2 
3 

現在我想用一臺發電機作爲輸入:

function *y() { 
    yield 5 
    yield 6 
    yield 7 
} 

這些不起作用:

x(y()) 
x(y) 

輸出是:

5 
6 
7 
undefined 

什麼我需要做的,這樣我可以使它發揮作用?

在Java方面,上面的功能y發生器y()迭代[1,2,3]是一個列表,在Java中,列表是生成器。但javascript for loop期望迭代器,這意味着它不能重新啓動。這看起來像是javascript中的一個缺陷,for循環對迭代器而不是生成器起作用。

回答

2

發電機cannot be used multiple times。如果你想迭代它兩次,你將需要通過調用兩次生成器函數來創建兩個生成器。

當你的函數需要一個迭代(即在for … of循環使用)是從您的發電機功能即時創建一個你可以做什麼:

x({[Symbol.iterator]: y}) 

如果你想要寫你的函數x以便它可以採用迭代器或生成器函數,您可以使用類似於

getIterator(val) { 
    if (typeof val == "function") // see also https://stackoverflow.com/q/16754956/1048572 
     return val(); 
    if (typeof val[Symbol.iterator] == "function") 
     return val[Symbol.iterator](); 
    throw new TypeError("not iterable!") 
} 
function x(l) { 
    for (let i of getIterator(l)) { 
     console.log(i); 
    } 
    for (let i of getIterator(l)) { // call getIterator again 
     console.log(i); 
    } 
} 
x(y); 
+1

好吧!我現在明白了。 y是一個生成器函數,y()是一個迭代器,你用Symbol.iterator寫的是一個可迭代的,可以重用的。 for循環可以獲得迭代器或迭代器。我想要一個迭代器,所以你的一行內容適合我。謝謝! – Eyal