This has more to do with how the for..of
operates than the reusability of the iterator. If you were to manually pull the next value of the iterator, you call it as many times as necessary and it would resume from the previous state.
Which makes something like this possible:
function* iter(a) {
yield* a;
}
let values = [1, 2, 3, 4, 5];
let it = iter(values)
for (let i = 0, n = values.length; i < n; i++) {
let x = it.next().value
console.log(x)
if (x === 3)
break
}
console.log('---')
for (let x of it) {
console.log(x)
}
And the same could be done for a while
loop that isn't dependent on a values
array:
function* iter(a) {
yield* a;
}
let it = iter([1, 2, 3, 4, 5]),
contin = true
while (contin && (x = it.next().value)) {
console.log(x)
if (x === 3)
contin = false
}
console.log('---')
for (let x of it) {
console.log(x)
}
The second example (while
loop) deviates slightly as x
is assigned during the condition evaluation. It assumes that all values of x
are truthy so undefined
can be used as a terminating condition. If that is not the case, it would need to be assigned in the loop block and a terminating condition would have to be set. Something like if(x===undefined)contin=false
or checking if the iterator has reached the end of its inputs.