Skip to content

Instantly share code, notes, and snippets.

@MKRhere
Last active June 14, 2021 16:23
Show Gist options
  • Save MKRhere/e99843c196de4ff51a0e5b74f3543099 to your computer and use it in GitHub Desktop.
Save MKRhere/e99843c196de4ff51a0e5b74f3543099 to your computer and use it in GitHub Desktop.
Merge AsyncIterables
function* map<T, U>(iter: Iterable<T>, f: (t: T) => U): Iterable<U> {
for (const i of iter) {
yield f(i);
}
}
export async function* merge<T>(iterables: AsyncIterable<T>[]) {
const racers = new Map<AsyncIterator<T>, Promise<IteratorResult<T>>>(
map(
map(iterables, (iter) => iter[Symbol.asyncIterator]()),
(iter) => [iter, iter.next()]
)
);
while (racers.size > 0) {
const winner = await Promise.race(
map(racers.entries(), ([iter, prom]) =>
prom.then((result) => ({ result, iter }))
)
);
if (winner.result.done) {
racers.delete(winner.iter);
} else {
yield await winner.result.value;
racers.set(winner.iter, winner.iter.next());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment