【发布时间】:2021-11-12 19:31:36
【问题描述】:
假设我有一个异步生成器,如下所示:
// This could be records from an expensive db call, for example...
// Too big to buffer in memory
const events = (async function* () {
await new Promise(r => setTimeout(r, 0));
yield {type:'bar', ts:'2021-01-01 00:00:00', data:{bar:"bob"}};
yield {type:'foo', ts:'2021-01-02 00:00:00', data:{num:2}};
yield {type:'foo', ts:'2021-01-03 00:00:00', data:{num:3}};
})();
我怎样才能复制它来达到类似的效果:
function process(events) {
async function* filterEventsByName(events, name) {
for await (const event of events) {
if (event.type === name) continue;
yield event;
}
}
async function* processFooEvent(events) {
for await (const event of events) {
yield event.data.num;
}
}
// How to implement this fork function?
const [copy1, copy2] = fork(events);
const foos = processFooEvent(filterEventsByName(copy1, 'foo'));
const bars = filterEventsByName(copy2, 'bar');
return {foos, bars};
}
const {foos, bars} = process(events);
for await (const event of foos) console.log(event);
// 2
// 3
for await (const event of bars) console.log(event);
// {type:'bar', ts:'2021-01-01 00:00:00', data:{bar:"bob"}};
【问题讨论】:
-
作为一个生成器,只实例化一次是没有意义的。只需保持生成器函数不变,并将其传递到
filterByName。 -
@MarioVernari 为了这个例子,我只是给出了一个简单的生成,实际上生成器是从一个我只想进行一次的昂贵的 API 调用创建的。
-
那么也许只有实际的 API 调用应该进行一次并缓存,而生成器应该仍然被实例化两次?
-
@CherryDT API 结果集太大而无法放入内存。
-
但这不合逻辑。让我们假设有一种复制生成器状态的方法(没有)。那这意味着什么?如果都是一个请求,那么响应将存储在哪里,如果不在内存中?如果以分页方式根据需要完成了多个请求,那么如果其中一个生成器副本已经被
next调用了 100 次而另一个被调用了 500 次,会发生什么?考虑到这一点,您会得出结论,唯一有意义的就是必须分离生成器。
标签: javascript generator