typescriptintermediate
Promise Pool for Batch Processing
Process large arrays with controlled concurrency using a promise pool pattern with progress tracking.
typescriptPress ⌘/Ctrl + Shift + C to copy
interface PoolOptions<T, R> {
items: T[];
concurrency: number;
handler: (item: T, index: number) => Promise<R>;
onProgress?: (completed: number, total: number) => void;
}
async function promisePool<T, R>(options: PoolOptions<T, R>): Promise<R[]> {
const { items, concurrency, handler, onProgress } = options;
const results: R[] = new Array(items.length);
let nextIndex = 0;
let completed = 0;
async function worker() {
while (nextIndex < items.length) {
const i = nextIndex++;
results[i] = await handler(items[i], i);
completed++;
onProgress?.(completed, items.length);
}
}
const workers = Array.from(
{ length: Math.min(concurrency, items.length) },
() => worker(),
);
await Promise.all(workers);
return results;
}
// Batch with chunking
async function processBatches<T, R>(
items: T[],
batchSize: number,
handler: (batch: T[], batchIndex: number) => Promise<R[]>,
): Promise<R[]> {
const results: R[] = [];
for (let i = 0; i < items.length; i += batchSize) {
const batch = items.slice(i, i + batchSize);
const batchResults = await handler(batch, Math.floor(i / batchSize));
results.push(...batchResults);
console.log(`Batch ${Math.floor(i / batchSize) + 1}: ${results.length}/${items.length}`);
}
return results;
}
// Usage
async function main() {
const urls = Array.from({ length: 50 }, (_, i) => `https://api.example.com/${i}`);
console.time('pool');
const results = await promisePool({
items: urls,
concurrency: 10,
handler: async (url, i) => {
await new Promise(r => setTimeout(r, Math.random() * 200));
return { url, ok: true };
},
onProgress: (done, total) => {
if (done % 10 === 0) console.log(`Progress: ${done}/${total}`);
},
});
console.timeEnd('pool');
console.log(`Processed ${results.length} items`);
}
main();Use Cases
- Bulk API requests
- Image processing pipelines
- Data migration scripts
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptintermediate
Promise Concurrency Patterns
Master Promise.all, allSettled, race, any — parallel execution with error handling and timeouts.
Best for: Parallel API calls with error handling
#nodejs#promise
typescriptadvanced
Node.js In-Memory Task Queue
A simple in-memory task queue with concurrency control, retries, and priority support.
Best for: Rate-limited API call processing
#nodejs#queue
typescriptintermediate
Semaphore for Concurrency Limiting
Control concurrent async operations with a semaphore pattern: rate limiting, connection pooling, and batch processing.
Best for: API rate limiting
#nodejs#concurrency
typescriptadvanced
Node.js Worker Threads for Parallel Processing
Use Worker Threads to run CPU-intensive tasks in parallel without blocking the event loop.
Best for: CPU-intensive data processing without blocking
#nodejs#worker-threads