Skip to content

Instantly share code, notes, and snippets.

@kirkegaard
Last active October 9, 2024 15:12
Show Gist options
  • Save kirkegaard/52ad8cfd6d59c2df04824db58a10b4f9 to your computer and use it in GitHub Desktop.
Save kirkegaard/52ad8cfd6d59c2df04824db58a10b4f9 to your computer and use it in GitHub Desktop.
JobQueue using Promises
// A job queue that takes an anonymous functions and executes them in parallel
class JobQueue {
constructor(maxConcurrent = 3) {
this.maxConcurrent = maxConcurrent;
this.queue = [];
this.activeCount = 0;
}
// Add task to queue and
exec(task) {
return new Promise((resolve, reject) => {
this.queue.push(() => {
return task().then(resolve).catch(reject);
});
this.next();
});
}
// Run the next task
next() {
if (this.activeCount < this.maxConcurrent && this.queue.length > 0) {
// Grab next task
const nextTask = this.queue.shift();
this.activeCount++;
// Run the task and reduce the active count once it's done
nextTask().finally(() => {
this.activeCount--;
this.next();
});
}
}
}
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const Job = async (id, delay) => {
console.log(`Task ${id} added`);
try {
await sleep(delay);
if (id === 2) {
throw new Error("err happened");
}
} catch (err) {
// Handle errors but dont kill the queue
console.error(err);
}
console.log(`Task ${id} done`);
};
const queue = new JobQueue(3);
queue.exec(() => Job(1, 1000));
queue.exec(() => Job(2, 750));
queue.exec(() => Job(3, 2000));
queue.exec(() => Job(4, 2500));
queue.exec(() => Job(5, 1000));
queue.exec(() => Job(6, 250));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment