export class AsyncQueue<T> implements AsyncIterable<T> { private queue: T[] = [] private resolvers: ((value: T) => void)[] = [] push(item: T) { const resolve = this.resolvers.shift() if (resolve) resolve(item) else this.queue.push(item) } async next(): Promise<T> { if (this.queue.length > 0) return this.queue.shift()! return new Promise((resolve) => this.resolvers.push(resolve)) } async *[Symbol.asyncIterator]() { while (true) yield await this.next() }} export async function work<T>(concurrency: number, items: T[], fn: (item: T) => Promise<void>) { const pending = [...items] await Promise.all( Array.from({ length: concurrency }, async () => { while (true) { const item = pending.pop() if (item === undefined) return await fn(item) } }), )}
export class AsyncQueue<T> implements AsyncIterable<T> {
private queue: T[] = []
private resolvers: ((value: T) => void)[] = []
push(item: T) {
const resolve = this.resolvers.shift()
if (resolve) resolve(item)
else this.queue.push(item)
}
async next(): Promise<T> {
if (this.queue.length > 0) return this.queue.shift()!
return new Promise((resolve) => this.resolvers.push(resolve))
}
async *[Symbol.asyncIterator]() {
while (true) yield await this.next()
}
}
export async function work<T>(concurrency: number, items: T[], fn: (item: T) => Promise<void>) {
const pending = [...items]
await Promise.all(
Array.from({ length: concurrency }, async () => {
while (true) {
const item = pending.pop()
if (item === undefined) return
await fn(item)
}
}),
)
}