简体   繁体   English

如何在for循环的ES6 javascript中重用生成器?

[英]How do I reuse a generator in ES6 javascript in for loops?

I'm trying to write a function that can take either a list or a generator as input. 我正在尝试编写一个可以将列表或生成器作为输入的函数。 For example, this function: 例如,此功能:

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

If I run it like this: 如果我这样运行:

x([1,2,3])

It will display: 它将显示:

1
2
3
1
2
3

Now I want to use a generator as input: 现在我想使用一个生成器作为输入:

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

These don't work: 这些不起作用:

x(y())
x(y)

The output is: 输出为:

5
6
7
undefined

What do I need to do so that I can make it work? 我需要做什么才能使它正常工作?

In terms of Java, the function y above is a Generator and y() is an Iterator . 就Java而言,上面的函数yGenerator,y()Iterator [1,2,3] is a list and in Java, lists are generators. [1,2,3]是一个列表,在Java中,列表是生成器。 But the javascript for loop expects an iterator , which means that it can't be restarted. 但是javascript for循环需要使用iterator ,这意味着它无法重新启动。 This seems like a flaw in javascript that the for loop works on iterators and not generators. 这似乎是javascript中的一个缺陷,for循环适用于迭代器而不是生成器。

A generator cannot be used multiple times . 生成器不能多次使用 If you want to iterate it twice, you will need to create two generators by calling the generator function twice. 如果要对其进行两次迭代,则需要通过两次调用generator函数来创建两个生成器。

What you can do when your function expects an iterable (that is used in a for … of loop) is to create one on the fly from your generator function: 当函数期望可迭代(在for … of循环中使用)时,您可以做的是通过生成器函数动态创建一个:

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

If you want to write your function x so that it can take either an iterator or a generator function, you can use something like 如果您想编写函数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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM