2

我有一个生成器通过我正在使用的库中的函数调用返回给我。然后我将这个生成器传递给一个函数,该函数遍历它并对每个项目执行一堆逻辑。然后我想在调用该函数后引用同一个生成器。但是,生成器似乎不再拥有/生成任何项目。代码如下:

let myGenerator = this.generatorFunc();
console.log(Array.from(myGenerator).length); //prints N which is specified elsewhere
this.iterateThroughGenerator(myGenerator);
console.log(Array.from(myGenerator).length); //now prints 0 when I need it to be N still

iterateThroughGenerator(generator) {
    for(let element of generator) {
        // do a bunch of stuff with element
    }
}
4

4 回答 4

1

这就是迭代器的工作方式。调用生成器会返回一个迭代器,它可以迭代一次。这在大多数其他语言中是相同的。

let generator = function* () {
  for (let i = 0; i < 3; i++) 
    yield i;
};

let iterator = generator();

console.log(Array.from(iterator)); // [1...3]
console.log(Array.from(iterator)); // []

console.log(Array.from(generator())); // [1..3]
console.log(Array.from(generator())); // [1..3]

于 2019-06-28T18:28:51.893 回答
1

其他人已经解释了为什么会发生这种情况,但我还是会回顾一下。

生成器函数返回一个生成器对象,它使用对自身的简单循环引用实现可迭代协议(一个Symbol.iterator属性)和迭代器协议(一种next()方法),以便有状态地迭代其生成器函数的控制流。

要解决您的问题,请使用实现可迭代协议的对象封装生成器函数调用,方法是返回生成器对象的单独实例,您可以以相同的方式使用它:

const iterable = { [Symbol.iterator]: () => this.generatorFunc() };

console.log(Array.from(iterable).length); //prints N which is specified elsewhere
this.iterateThroughGenerator(iterable);
console.log(Array.from(iterable).length); //still prints N

iterateThroughGenerator(iterable) {
    for(let element of iterable) {
        // do a bunch of stuff with element
    }
}
于 2019-06-28T18:52:33.390 回答
0

生成器功能完成后,您必须调用 this.getGeneratorFunc() 再次重新创建生成器。此外,当您执行 Array.from(myGenerator) 时,它也会完成该生成器,因此当您调用 this.iterateThroughGenerator(myGenerator) 时,将不会发生任何事情,因为不再从生成器返回任何元素。因此,您可以将生成器的结果保存到数组中并重用该数组,或者每次要从中获取元素时调用 this.getGeneratorFunc() 三次。在这个具体的例子中,我会做

 const generated = Array.from(this.getGeneratorFunc());
 console.log(generated.length);
 this.iteratedItems(generated);
 console.log(generated.length);

也看看这个答案。以前的答案
ID 也读过这个

于 2019-06-28T18:27:40.560 回答
0

Array.from()耗尽生成器(迭代它直到结束),并且进一步迭代它不会产生更多元素。next()呼叫将始终返回{value: undefined, done: true}

要创建一个从头开始的新生成器,您需要再次调用generatorFunc()

于 2019-06-28T18:28:23.470 回答