* Execute promises with limited concurrency * * @param items - Items to process * @param fn - Async function to apply to each item * @param concurrency - Maximum concurrent operations * @returns Results in the same order as input items
( items: T[], fn: (item: T, index: number) => Promise<R>, concurrency: number, )
| 278 | * @returns Results in the same order as input items |
| 279 | */ |
| 280 | async function parallelWithLimit<T, R>( |
| 281 | items: T[], |
| 282 | fn: (item: T, index: number) => Promise<R>, |
| 283 | concurrency: number, |
| 284 | ): Promise<R[]> { |
| 285 | const results: R[] = new Array(items.length) |
| 286 | let currentIndex = 0 |
| 287 | |
| 288 | async function worker(): Promise<void> { |
| 289 | while (currentIndex < items.length) { |
| 290 | const index = currentIndex++ |
| 291 | const item = items[index] |
| 292 | if (item !== undefined) { |
| 293 | results[index] = await fn(item, index) |
| 294 | } |
| 295 | } |
| 296 | } |
| 297 | |
| 298 | // Start workers up to the concurrency limit |
| 299 | const workers: Promise<void>[] = [] |
| 300 | const workerCount = Math.min(concurrency, items.length) |
| 301 | for (let i = 0; i < workerCount; i++) { |
| 302 | workers.push(worker()) |
| 303 | } |
| 304 | |
| 305 | await Promise.all(workers) |
| 306 | return results |
| 307 | } |
| 308 | |
| 309 | /** |
| 310 | * Downloads all file attachments for a session in parallel |
no test coverage detected