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
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() |