This question already has answers here:
How can I Interleave / merge async iterables?
(5个答案)
2年前关闭。
我已经为此苦了一段时间。
在给定n个异步生成器的情况下,您将如何编写一个异步生成器,以它们到达的顺序从n个生成器中产生值。
该方法应采用以下格式:
例如:
它是预先重构的,所以请记住,它还不是很干净。
有趣的代码称为
它也使用此处包含的
使用修改后的
更新:现在它是一个npm模块https://github.com/hesher/mergen
(5个答案)
2年前关闭。
我已经为此苦了一段时间。
在给定n个异步生成器的情况下,您将如何编写一个异步生成器,以它们到达的顺序从n个生成器中产生值。
该方法应采用以下格式:
const merged = merge([gen1, gen2,...])
例如:
gen1 and gen2 are async generators.
gen1() yields 2 values: 1 in 100ms, 3 in 300ms
gen2() yields 2 values: 2 in 200ms, 4 in 400ms
merge([gen1, gen2]) will yield 1, 2, 3, 4 (in that order, every 100ms)
最佳答案
所以...经过数天的尝试来解决这个问题。
此方法有效(只需在打开实验标记的情况下将粘贴复制到最新的Chrome中)
function timer(time = 500) {
return new Promise(resolve => setTimeout(() => resolve(), time));
}
async function* gen1() {
await timer(100);
yield 1;
await timer(300);
yield 4;
}
async function* gen2() {
await timer(200);
yield 2;
await timer(100);
yield 3;
}
function race(promises) {
return new Promise(resolve =>
promises.forEach((p, index) => {
p.then(value => {
resolve({index, value});
});
})
);
}
async function* mergen(...gens) {
let promises = gens.map((gen, index) =>
gen.next().then(p => ({...p, gen}))
);
while (promises.length > 0) {
yield race(promises)
.then(({index, value: {value, done, gen}}) => {
promises.splice(index, 1);
if (!done)
promises.push(
gen.next().then(({value: newVal, done: newDone}) => ({
value: newVal,
done: newDone,
gen
}))
);
return value;
});
}
}
async function printGen(gen) {
let max = 10;
for await (x of gen) {
if (x) console.log('Next up:', x);
if (--max <= 0) break;
}
}
printGen(mergen(gen1(), gen2())); // 1, 2, 3, 4
它是预先重构的,所以请记住,它还不是很干净。
有趣的代码称为
mergen()
(明白吗?merge-gen?)它也使用此处包含的
Promise.race()
的修改版本。使用修改后的
race
的原因是因为我需要拥有首先完成的承诺的索引。更新:现在它是一个npm模块https://github.com/hesher/mergen
关于javascript - 同时等待2个(或更多)异步生成器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50657905/
10-16 00:33