Предположим, у меня есть некоторые asnyc итерируемые объекты, подобные этому:
// Promisified sleep function
const sleep = ms => new Promise((resolve, reject) => {
setTimeout(() => resolve(ms), ms);
});
const a = {
[Symbol.asyncIterator]: async function * () {
yield 'a';
await sleep(1000);
yield 'b';
await sleep(2000);
yield 'c';
},
};
const b = {
[Symbol.asyncIterator]: async function * () {
await sleep(6000);
yield 'i';
yield 'j';
await sleep(2000);
yield 'k';
},
};
const c = {
[Symbol.asyncIterator]: async function * () {
yield 'x';
await sleep(2000);
yield 'y';
await sleep(8000);
yield 'z';
await sleep(10000);
throw new Error('You have gone too far! ');
},
};
Теперь предположим, что я могу конкатрировать их так:
const abcs = async function * () {
yield * a;
yield * b;
yield * c;
};
Полученные (первые 9) предметы будут:
(async () => {
const limit = 9;
let i = 0;
const xs = [];
for await (const x of abcs()) {
xs.push(x);
i++;
if (i === limit) {
break;
}
}
console.log(xs);
})().catch(error => console.error(error));
// [ 'a', 'b', 'c', 'i', 'j', 'k', 'x', 'y', 'z' ]
Но представьте, что меня не волнует порядок, что a
, b
и c
работают c
разной скоростью и что я хочу уступить как можно быстрее.
Как я могу переписать этот цикл так, чтобы x
получен как можно скорее, игнорируя порядок?
Также возможно, что a
, b
или c
являются бесконечными последовательностями, поэтому решение не должно требовать буферизации всех элементов в массив.