Last active
October 9, 2024 15:12
-
-
Save kirkegaard/52ad8cfd6d59c2df04824db58a10b4f9 to your computer and use it in GitHub Desktop.
JobQueue using Promises
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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