如何在for循环中重用ES6 javascript中的生成器? [英] How do I reuse a generator in ES6 javascript in for loops?

查看:132
本文介绍了如何在for循环中重用ES6 javascript中的生成器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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);
    }
}

如果我这样运行:

x([1,2,3])

它将显示:

1
2
3
1
2
3

现在我想使用发电机作为输入:

Now I want to use a generator as input:

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

这些不起作用:

x(y())
x(y)

输出为:

5
6
7
undefined

我需要做些什么才能让它发挥作用?

What do I need to do so that I can make it work?

就Java而言,上面的函数 y 生成器 y() Iterator [1,2,3] 是一个列表,在Java中,列表是生成器。但是javascript for循环需要迭代器,这意味着它无法重新启动。这似乎是javascript中的缺陷,for循环可以在迭代器而不是生成器上运行。

In terms of Java, the function y above is a Generator and y() is an Iterator. [1,2,3] is a list and in Java, lists are generators. But the javascript for loop expects an iterator, which means that it can't be restarted. This seems like a flaw in javascript that the for loop works on iterators and not generators.

推荐答案

生成器不能多次使用。如果你想迭代它两次,你需要通过调用生成器函数两次创建两个生成器。

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.

当你的函数期望迭代时你可以做什么(即在中用于...的循环)是从你的生成器函数动态创建一个:

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:

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

如果你想要编写你的函数 x 以便它可以使用迭代器或生成器函数,你可以使用像

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

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);

这篇关于如何在for循环中重用ES6 javascript中的生成器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆