我创建了一个函数foo,如下所示
function* foo(){
var index = 0;
while (index <= 2)
yield index++;
}
当我调用以下函数时给出相同的输出
console.log(foo().next()); //Object {value: 0, done: false}
console.log(foo().next()); //Object {value: 0, done: false}
console.log(foo().next()); //Object {value: 0, done: false}
但是当我尝试跟随给出输出作为例外
var xx=foo();
console.log(xx.next()); //Object {value: 0, done: false}
console.log(xx.next()); //Object {value: 1, done: false}
console.log(xx.next()); //Object {value: 2, done: false}
console.log(xx.next()); //Object {value: undefined, done: true}
我只是想了解其背后的原因,为什么会发生这种情况
答案 0 :(得分:4)
生成器函数在调用时返回Iterator。再次调用生成器会返回一个新的迭代器。
这是一个如何运作的例子:
function* countdown(start){
while (start > 0)
yield start--;
}
var countdown1 = countdown(10);
var countdown2 = countdown(20);
现在我们有2&#34;直播&#34;倒计时迭代器,第一个将产生10..1,第二个将产生20..1。我们可以在每个独立于另一个上调用.next()
并且状态得到正确维护:
console.log(countdown1.next().value) // 10
console.log(countdown1.next().value) // 9
console.log(countdown1.next().value) // 8
console.log(countdown2.next().value) // 20
console.log(countdown2.next().value) // 19
console.log(countdown2.next().value) // 18
console.log(countdown1.next().value) // 7
console.log(countdown1.next().value) // 6
console.log(countdown1.next().value) // 5
迭代器不必由生成器生成...但是对象作为迭代器所需要的是它具有next()
成员函数,该函数返回带有签名的对象{value: x, done: trueOrFalse}
。但是,要充分利用此模式,您需要将其附加到可迭代。 Iterable是一个具有[Symbol.iterator]
属性的对象,它返回一个迭代器。例如:
function nonGeneratorCountdown() {
return {
next: arg => {
if (this.count > 0) {
return {value: this.count--, done: false};
}
return {done: true};
}
};
}
var iterable = {
count: 3,
[Symbol.iterator]: nonGeneratorCountdown
};
for(let i of iterable) {
console.log(i); // 3, 2, 1
}
所以...在你的代码中:
console.log(foo().next());
始终返回一个新的迭代器,在其上调用.next()
并记录返回的值。
var xx=foo();
console.log(xx.next());
console.log(xx.next());
另一方面,只使用一个迭代器多次,并记录迭代(和更改)的结果。