javascript 中断 for-await 循环完成生成器
javascript break in for-await loop finish the generator
我编写了这段代码来迭代 github 个具有特定数字的问题(如分页),在本例中一次有 3 个问题:
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());
});
具有data-next 属性的元素是一个按钮。预期的行为是每次单击按钮都会加载接下来的 3 期。问题是,生成器在中断后完成(console.log 打印:{value: undefined, done: true}
)。
为什么它完成了,我怎样才能让它按预期工作?
众所周知 problem/feature,for..of
终止生成器(参见 )。一种可能的解决方案是提供一个代理,它将在闭包中保留实际的生成器状态:
function persist(gen) {
return {
next() {
return gen.next()
},
[Symbol.asyncIterator]() {
return this
},
[Symbol.iterator]() {
return this
}
}
}
//
const getUrl = (page) => `https://jsonplaceholder.typicode.com/posts/${page}/comments`;
const getIssues = async function* () {
for (let p = 1; true; p++) {
const url = getUrl(p)
const raw = await fetch(url)
const data = await raw.json()
yield* data
}
};
async function main() {
const generator = persist(getIssues());
let i = 0;
for await (let x of generator) {
console.log(i, x.postId, x.id, x.name);
if (++i === 4) break;
}
console.log('break'); i = 0;
for await (let x of generator) {
console.log(i, x.postId, x.id, x.name);
if (++i === 4) break;
}
console.log('break'); i = 0;
for await (let x of generator) {
console.log(i, x.postId, x.id, x.name);
if (++i === 4) break;
}
}
main()
我编写了这段代码来迭代 github 个具有特定数字的问题(如分页),在本例中一次有 3 个问题:
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());
});
具有data-next 属性的元素是一个按钮。预期的行为是每次单击按钮都会加载接下来的 3 期。问题是,生成器在中断后完成(console.log 打印:{value: undefined, done: true}
)。
为什么它完成了,我怎样才能让它按预期工作?
众所周知 problem/feature,for..of
终止生成器(参见
function persist(gen) {
return {
next() {
return gen.next()
},
[Symbol.asyncIterator]() {
return this
},
[Symbol.iterator]() {
return this
}
}
}
//
const getUrl = (page) => `https://jsonplaceholder.typicode.com/posts/${page}/comments`;
const getIssues = async function* () {
for (let p = 1; true; p++) {
const url = getUrl(p)
const raw = await fetch(url)
const data = await raw.json()
yield* data
}
};
async function main() {
const generator = persist(getIssues());
let i = 0;
for await (let x of generator) {
console.log(i, x.postId, x.id, x.name);
if (++i === 4) break;
}
console.log('break'); i = 0;
for await (let x of generator) {
console.log(i, x.postId, x.id, x.name);
if (++i === 4) break;
}
console.log('break'); i = 0;
for await (let x of generator) {
console.log(i, x.postId, x.id, x.name);
if (++i === 4) break;
}
}
main()