-
Notifications
You must be signed in to change notification settings - Fork 66
Recipes
chetanism edited this page Jun 17, 2020
·
2 revisions
Use Case:
This is mostly useful when you want to use the queue
as a concurrency control.
The idea here is to define a wrapper class that will have just a single instance to enqueue jobs and provides a simple API returning a promise that resolves or rejects depending on job fails or completes.
This may be useful to minimise the impact of using queue in your existing codebase e.g. const result = await foo(bar);
changes to const result = await myQueue.addJob(() => foo(bar));
You can define a wrapper class for your queue
class MyJobQueue {
private theQueue;
private jobResolveRejectMap = new Map();
constructor() {
this.theQueue = queue(/* Your options */);
this.theQueue.on('success', this.onJobComplete.bind(this));
this.theQueue.on('error', this.onJobFailed.bind(this));
}
async addJob(job): Promise<any> {
this.theQueue.push(job);
return new Promise((resolve, reject) => {
this.jobResolveRejectMap.set(job, { resolve, reject });
});
}
onJobComplete(result, job) {
const { resolve } = this.jobResolveRejectMap.get(job);
this.jobResolveRejectMap.delete(job);
resolve(result);
}
onJobFailed(error, job) {
const { reject } = this.jobResolveRejectMap.get(job);
this.jobResolveRejectMap.delete(job);
reject(error);
}
}
It can then be used as:
// You'll probably need just a single instance
const myQueue: MyJobQueue = new MyJobQueue();
const result = await myQueue.addJob(() => {
return new Promise(resolve => {
setTimeout(() => resolve(42), 100);
});
})
// result === 42
Caveats:
- To handle synchronous jobs the class may need a few tweaks.