Extremely simplistic and tiny AsyncPool for limiting concurrency of async operations. Contains zero dependencies beside Node.js native ones.
const { AsyncPool } = require('@metcoder95/tiny-pool');
async () => {
const asyncPool = new AsyncPool({ maxConcurrent: 5, maxEnqueued: 100 });
asyncPool.on('flushed', () => console.log('queue is flushed'));
asyncPool.on('drained', () => console.log('pool is drained'));
for (let i = 0; i < 20; i++) {
asyncPool.run(() => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(i);
}, 1000);
});
});
if (i === 10) {
const result = await asyncPool.drain();
console.log('Queue drained:', result);
} else if (i === 15) {
const result = await asyncPool.flush();
console.log('Pool flushed:', result);
}
}
await once(asyncPool, 'idle').then(console.log('done'));
};
import { AsyncPool, AsyncPoolOptions } from '@metcoder95/tiny-pool';
async () => {
const options: AsyncPoolOptions = {
maxEnqueued: 100,
};
const asyncPool = new AsyncPool({ maxConcurrent: 5, maxEnqueued: 100 });
asyncPool.on('flushed', () => console.log('queue is flushed'));
asyncPool.on('drained', () => console.log('pool is drained'));
for (let i = 0; i < 20; i++) {
asyncPool.run(() => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(i);
}, 1000);
});
});
if (i === 10) {
const result = await asyncPool.drain();
console.log('Queue drained:', result);
} else if (i === 15) {
const result = await asyncPool.flush();
console.log('Pool flushed:', result);
}
}
await once(asyncPool, 'idle').then(console.log('done'));
};
type AsyncPoolOptions = {
/**
* Indicates the maximum number of concurrent tasks being executed
*
* @default 5
* @type {number}
*/
maxConcurrent?: number;
/**
* Specifies the maximum number of tasks being enqueued for posterior execution
* @default 10
* @type {number}
*/
maxEnqueued?: number;
};
Signature
run<Result = unknown>(task: Promise<Result>): AsyncPoolTask<Result>
Executes the given async task. The task should return a Promise. The function returns a Promise that will either resolve with the value returned by the Promise or reject in case of a failure
Signature
clear(): void
The function will clear the queue, avoiding the execution of the tasks within.
Signature
flush(): Promise<AsyncPoolTask[]>
Will flush all the enqueued and current running tasks
blocking for any new incoming one of being enqueued.
Will emit the event flushed
once the queue is empty.
Signature
drain(): Promise<AsyncPoolTask[]>
It will until all the tasks that are currently running are
done being executed. Enqueueing is still possible but it will
not execute any enqueued tasks until the draining is done.
It will emit the event drained
once done.
The AsyncPool
class extends from the EventEmitter
from Node.js.
For instance is possible to listen for a couple of events that might be helpful when using the pool.
It indicates the full pool has been flushed. Is emitted after the execution of the flush
function.
Will be emitted onceall the running tasks are being executed. It's only emitted after the execution of drain
function.
Only emitted when the queue is empty and the current tasks finished its execution. This can be a good moment to continue appending more tasks to the pool.