我有一个发电机通过我使用的库中的函数调用返回给我。然后,我将此发电机传递给遍历它的函数,并对每个项目进行一堆逻辑。然后,我想在调用该功能后引用同一生成器。但是,似乎发电机不再有/生成任何项目。代码沿着这些行:
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
}
}
这就是迭代器的工作方式。调用发电机返回迭代器,可以迭代一次。在大多数其他语言中都是相同的。
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]
其他人已经解释了为什么会发生这种情况,但无论如何我都会回顾。
生成器函数返回一个生成器对象,该对象使用简单的圆形引用来实现峰值协议( 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
}
}
完成生成器函数后,您必须调用this.getGeneratorFunc((再次重新创建生成器。另外,当您执行array.from(mygenerator(时,它也将完成该发电机,因此当您调用this.iteratethroughgenerator(myGenererator(时,什么也不会发生,因为没有从生成器返回的元素。因此,您可以将生成器的结果保存到一个数组中并重复使用该数组,或者每次要从中获取元素时调用This.getGeneratorFunc((。在这个具体示例中,我会做
const generated = Array.from(this.getGeneratorFunc());
console.log(generated.length);
this.iteratedItems(generated);
console.log(generated.length);
也请查看此答案。以前的答案
id也阅读此。
Array.from()
耗尽了发电机(迭代直至结束(,然后将其进一步迭代不会产生更多的元素。next()
呼叫将始终返回{value: undefined, done: true}
。
要创建一个从头开始开始的新发电机,您需要再次调用generatorFunc()
。