Is it possible to loop over part of an iterator with for...of
without closing the iterator when I break the loop?
Example:
function* numbers(i=0){
while(true) yield i++;
}
let nums=numbers();
// this loop prints numbers from 0 to 3
for(const n of nums){
if(n>3) break;
console.log(n);
}
// this loop doesn't print anything because `nums` has already been closed
for(const n of nums){
if(n>10) break;
console.log(n);
}
I know that I can go through the iterator on my own calling iterator.next()
. But I wonder if it's possible to do this with the for...of
syntax.
No. However you can provide a wrapper that doesn't forward return()
to the generator:
function unclosed(iterable) {
return {
[Symbol.iterator]() {
const iterator = iterable[Symbol.iterator]();
return {
next: iterator.next.bind(iterator),
return: null,
throw: null,
};
},
};
}
function* numbers(i=0) {
try {
while (true) yield i++;
} finally {
console.log('done');
}
}
const nums = numbers();
// this loop prints numbers from 0 to 3
for (const n of unclosed(nums)) {
console.log(n);
if (n == 3) break;
}
// and this one the numbers from 4 to 10, as well as 'done'
for (const n of nums) {
console.log(n);
if (n == 10) break;
}