如何循环遍历来自生成器的JavaScript迭代器?

14

假设我们有以下生成器:

var gen = function* () {
  for (var i = 0; i < 10; i++ ) {
    yield i;
  }
};

如何以最有效的方式循环遍历迭代器? 目前我通过手动检查done属性是否设置为true

var item
  , iterator = gen();

while (item = iterator.next(), !item.done) {
  console.log( item.value );
}

1
下面是一个返回对象的函数:iterator.next().valueiterator.next().done,所以它应该是 item().valueitem().done - Sabaz
如果您的浏览器支持 for...of,请随意使用它。 - Frédéric Hamidi
2个回答

18

迭代任何可迭代对象(支持@@iterator的对象),最好的方法是使用for..of,如下所示

'use strict';

function * gen() {
    for (var i = 0; i < 10; i++) {
        yield i;
    }
}

for (let value of gen()) {
    console.log(value);
}

或者,如果你想要一个数组,你可以使用Array.from来实现,像这样:

console.log(Array.from(gen());
// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

@thefourtheye,在Firefox 42中,const value of gen()会触发错误(SyntaxError: invalid for/in left-hand side)。使用let value of gen()即可。 - Frédéric Hamidi
@FrédéricHamidi 你能否尝试在严格模式下运行吗? - thefourtheye
是的,我做了(fiddle)。可能是Firefox的问题。 - Frédéric Hamidi
@RGraham,这是让let被识别的必要条件。在“普通”JavaScript模式下,既不支持const value of,也不支持let value of(但支持var value of)。 - Frédéric Hamidi
但是JS1.7不是ES6的实现,对吧?“纯”JavaScript将触发FF42的本地实现,该实现应该完全支持ECMAScript constfor..of。或者我可能对JS1.7的实现感到困惑。 - CodingIntrigue
显示剩余2条评论

6

在这个问题中,一个自包含的、单行的替代while循环的方法是for循环。对于纯粹的副作用或消耗迭代的特殊情况,而不是在结束时对结果进行处理,我们可以避免绑定下一个项目值,然后在for-of解决方案中不使用它:

for (let n = iterator.next(); !n.done; n = iterator.next()) {}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接