(...iterables: AsyncIterable<T>[])
| 247 | * ``` |
| 248 | */ |
| 249 | export async function* mergeAsyncIterables<T>(...iterables: AsyncIterable<T>[]): AsyncIterable<T> { |
| 250 | const asyncIterators = iterables.map((iterable) => iterable[Symbol.asyncIterator]()); |
| 251 | const results = []; |
| 252 | let count = asyncIterators.length; |
| 253 | const never: Promise<never> = new Promise(() => {}); |
| 254 | async function getNext(asyncIterator: AsyncIterator<T>, index: number) { |
| 255 | const result = await asyncIterator.next(); |
| 256 | return { |
| 257 | index, |
| 258 | result, |
| 259 | }; |
| 260 | } |
| 261 | const nextPromises = asyncIterators.map(getNext); |
| 262 | try { |
| 263 | while (count) { |
| 264 | const { index, result } = await Promise.race(nextPromises); |
| 265 | if (result.done) { |
| 266 | nextPromises[index] = never; |
| 267 | results[index] = result.value; |
| 268 | count--; |
| 269 | } else { |
| 270 | nextPromises[index] = getNext(asyncIterators[index], index); |
| 271 | yield result.value; |
| 272 | } |
| 273 | } |
| 274 | } finally { |
| 275 | for (const [index, iterator] of asyncIterators.entries()) { |
| 276 | // no await here - see https://github.com/tc39/proposal-async-iteration/issues/126 |
| 277 | if (nextPromises[index] !== never && iterator.return != null) void iterator.return(); |
| 278 | } |
| 279 | } |
| 280 | return results; |
| 281 | } |
no test coverage detected
searching dependent graphs…