2017-11-11 105 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