Skip to content

Instantly share code, notes, and snippets.

@huynhducduy
Last active July 28, 2022 11:00
Show Gist options
  • Save huynhducduy/089aa77b2c71a081fc45ecc9f3757a4a to your computer and use it in GitHub Desktop.
Save huynhducduy/089aa77b2c71a081fc45ecc9f3757a4a to your computer and use it in GitHub Desktop.
Javascript worker queue problem.
new Worker().eat().sleep(2).work().sleep(2).eat().work()

Get this to print

eat
// wait for 2 seconds
work
// wait for 2 seconds
eat
work
// This solution with block the event-loop => only 1 worker can run at a time
class Worker {
sleep(second) {
const time = Date.now();
while (Date.now() - time < second * 1000) {
}
return this;
}
eat() {
console.log('eat')
return this;
}
work() {
console.log('work')
return this
}
}
new Worker().eat().sleep(2).work().sleep(2).eat().work()
// This solution make use of the macro-queue of Web Timer, multiple worker can run at a time
class Worker2 {
queue = []
constructor() {
setTimeout(async () => {
for (const job of this.queue) {
await new Promise(resolve => setTimeout(() => {
job[0]()
resolve()
}, job[1] * 1000))
}
}, 0)
}
sleep(second) {
this.queue.push([() => {}, second])
return this
}
eat() {
this.queue.push([() => console.log('eat'), 0])
return this
}
work() {
this.queue.push([() => console.log('work'), 0])
return this
}
}
new Worker2().eat().sleep(2).work().sleep(2).eat().work()
// This solution make use micro-queue of promises (higher priority than macro-queue), multiple worker can run at a time
function Worker3() {
this.taskQueue = Promise.resolve();
this.addTask = f => {
this.taskQueue = this.taskQueue.then(f);
}
this.sleep = function(timer) {
this.addTask(() => new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, timer * 1000);
}))
return this;
}
this.eat = function() {
this.addTask(() => console.log('eat'));
return this;
}
this.work = function() {
this.addTask(() => console.log('work'));
return this;
}
}
new Worker3().eat().sleep(2).work().sleep(2).eat().work()
// Simple solution by treating sleepDuration as a queue
class Worker4 {
sleepDuration = 0
sleep(second) {
this.sleepDuration += second * 1000
return this
}
eat() {
setTimeout(() => console.log('eat'), this.sleepDuration)
return this
}
work() {
setTimeout(() => console.log('work'), this.sleepDuration)
return this
}
}
new Worker4().eat().sleep(2).work().sleep(2).eat().work()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment