I have written this code to iterate over github issues with a specific number (like pagination), in this case with 3 issues at once:
const getUrl = (page) => `https://api.github.com/repos/angular/angular/issues?page=${page}`;
const getIssues = async function*() {
for (let p = 1; true; p++) {
const url = getUrl(p);
const rawData = await fetch(url, {
headers: { 'User-Agent': 'app' }
});
const issues = await rawData.json();
for (let issue of issues) {
yield issue;
}
}
};
const generator = getIssues();
document.querySelector('[data-next]').addEventListener('click', async function() {
let i = 0;
for await (let issue of generator) {
console.log(issue);
if (++i === 3) break;
}
console.log(await generator.next());
});
The element with data-next attribute is a button. The expected behavior is every click on the button loads the next 3 issues. The problem is, the generator finished after the break (the console.log prints this: {value: undefined, done: true}
).
Why it is finished, and how could I make this work as expected?
It's a known problem/feature, that
for..of
terminates the generator (see e.g. here). One possible solution is to provide a proxy which will persist the actual generator state in a closure: