I have an array that contains an array of promises, and each inner array could have either 4k, 2k or 500 promises.
In total there are around 60k promises and I may test
A simple implementation where you can have a queue of tasks batched to run in parallel and add more dynamically:
class TaskQueue {
constructor ({
makeTask,
initialData = [],
getId = data => data.id,
batchSize = 15,
onComplete = () => {},
}) {
if (!makeTask) throw new Error('The "makeTask" parameter is required');
this.makeTask = makeTask;
this.getId = getId;
this.batchSize = batchSize;
this.onComplete = onComplete;
this.queue = new Map();
this.add(initialData);
}
add(...data) {
data.forEach(item => {
const id = this.getId(item);
if (this.queue.has(id)) return;
this.queue.set(id, item);
});
// running automatically on create or additional items added
this.runNextBatch();
}
runNextBatch () {
if (this.queueStarted) return;
if (this.queue.size === 0) return;
this.queueStarted = true;
const currentBatchData = Array.from(this.queue.values()).slice(0, this.batchSize);
const tasks = currentBatchData.map(data => {
const id = this.getId(data);
// Have some error handling implemented in `makeTask`
this.makeTask(data)
.finally(() => this.queue.delete(id));
});
return Promise.all(tasks)
.then(() => {
this.queueStarted = false;
this.runNextBatch();
})
.finally(() => {
this.queueStarted = false;
if (this.queue.size === 0) this.onComplete();
});
}
}
// Usage
const lotOfFilesForUpload = [{ uri: 'file://some-path' }, { uri: 'file://some-other-path' }];
const upload = (file) => console.log('fake uploading file: ', file);
const taskQueue = new TaskQueue({
initialData: lotOfFilesForUpload,
getId: file => file.uri,
makeTask: file => upload(file),
onComplete: () => console.log('Queue completed'),
});
// You can add more tasks dynamically
taskQueue.add({ uri: 'file://yet-another-file' });