| 1 | export class AsyncQueue<T> implements AsyncIterable<T> { |
| 2 | private queue: T[] = [] |
| 3 | private resolvers: ((value: T) => void)[] = [] |
| 4 | |
| 5 | push(item: T) { |
| 6 | const resolve = this.resolvers.shift() |
| 7 | if (resolve) resolve(item) |
| 8 | else this.queue.push(item) |
| 9 | } |
| 10 | |
| 11 | async next(): Promise<T> { |
| 12 | if (this.queue.length > 0) return this.queue.shift()! |
| 13 | return new Promise((resolve) => this.resolvers.push(resolve)) |
| 14 | } |
| 15 | |
| 16 | async *[Symbol.asyncIterator]() { |
| 17 | while (true) yield await this.next() |
| 18 | } |
| 19 | } |
| 20 | |
| 21 | export async function work<T>(concurrency: number, items: T[], fn: (item: T) => Promise<void>) { |
| 22 | const pending = [...items] |
nothing calls this directly
no outgoing calls
no test coverage detected