import {TaskQue} from './TaskQue'; export interface ITaskExecuter { execute(input: I): Promise; } export class TaskExecuter implements ITaskExecuter { private taskQue = new TaskQue(); private taskInProgress = 0; private run = async () => { if (this.taskQue.isEmpty() || this.taskInProgress >= this.size) { return; } this.taskInProgress++; const task = this.taskQue.get(); try { task.promise.resolve(await this.worker(task.data)); } catch (err) { task.promise.reject(err); } this.taskQue.ready(task); this.taskInProgress--; process.nextTick(this.run); }; constructor(private size: number, private worker: (input: I) => Promise) { } execute(input: I): Promise { const promise = this.taskQue.add(input).promise.obj; this.run().catch(console.error); return promise; } }