Skip to content

Instantly share code, notes, and snippets.

@frangio
Last active November 5, 2022 16:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save frangio/ddc4b1b96a5ac402526f59760416c162 to your computer and use it in GitHub Desktop.
Save frangio/ddc4b1b96a5ac402526f59760416c162 to your computer and use it in GitHub Desktop.
export async function* concurrently<T>(...gs: AsyncGenerator<T, void>[]): AsyncGenerator<T, void> {
const k = (i: number) => (res: IteratorResult<T>) => [i, res] as const;
const running = new Set(gs);
try {
const ps = gs.map((g, i) => g.next().then(k(i)));
const queue = new Set(ps);
while (queue.size > 0) {
const [i, res] = await Promise.race(queue);
const g = gs[i]!;
queue.delete(ps[i]!);
if (res.done) {
running.delete(g);
} else {
const p = ps[i] = g.next().then(k(i));
queue.add(p);
yield res.value;
}
}
} finally {
await Promise.all(Array.from(running, g => g.return()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment