【问题标题】:How do I reuse a generator in ES6 javascript in for loops?如何在 for 循环中重用 ES6 javascript 中的生成器?
【发布时间】:2018-04-24 14:36:09
【问题描述】:

我正在尝试编写一个可以将列表或生成器作为输入的函数。比如这个函数:

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是一个Generatory()是一个Iterator[1,2,3] 是一个列表,在 Java 中,列表是生成器。但是 javascript for 循环需要一个 iterator,这意味着它无法重新启动。这似乎是 javascript 中的一个缺陷,即 for 循环适用于迭代器而不是生成器。

【问题讨论】:

    标签: javascript ecmascript-6 iterator generator


    【解决方案1】:

    一个生成器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);
    

    【讨论】:

    • 好的!我现在明白了。 y 是生成器函数,y() 是迭代器,而您使用 Symbol.iterator 编写的内容是可迭代的,可以重用。 for 循环可以获得迭代器或可迭代对象。我想要一个可迭代的,所以你的单线对我有用。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    • 2021-07-15
    • 2016-07-23
    • 2015-06-16
    相关资源
    最近更新 更多