3

I have a scenario where I need to schedule multiple timeouts in vanilla JS, it will be something like this below:

const scheduler = {
  done: function() {},
  schedule: function() {}
};
scheduler.schedule(function(done) {
  setTimeout(() => {
    console.log(1);
    done()
  }, 2000);
});
scheduler.schedule(function(done) {
  setTimeout(() => {
    console.log(2);
    done()
  }, 1000);
});
scheduler.schedule(function(done) {
  setTimeout(() => {
    console.log(3);
    done()
  }, 3000);
});


it should execute it in such a way that it must print below:

1
2
3
FZs
  • 16,581
  • 13
  • 41
  • 50
Asutosh
  • 1,775
  • 2
  • 15
  • 22

3 Answers3

3

This is a nice use case of promises.

These objects allow the abstraction over asynchronous operations, and fortunately, can be chained.

const scheduler = {
  last: Promise.resolve(),
  schedule(cb){
    this.last = this.last.then(() => new Promise(cb))
  }
}
scheduler.schedule(function(done) {
  setTimeout(() => {
    console.log(1);
    done()
  }, 2000);
});
scheduler.schedule(function(done) {
  setTimeout(() => {
    console.log(2);
    done()
  }, 1000);
});
scheduler.schedule(function(done) {
  setTimeout(() => {
    console.log(3);
    done()
  }, 3000);
});

However, if you use this with promises you obtained from elsewhere , it can quickly turn into the Explicit Promise construction antipattern, so, for a more general code, move the new Promise() part out of the schedule method:

const scheduler = {
  last: Promise.resolve(),
  schedule(cb){
    this.last = this.last.then(cb)
  }
}
scheduler.schedule(function() {
  return new Promise(done => {
    setTimeout(() => {
      console.log(1);
      done()
    }, 2000);
  })
});
scheduler.schedule(function() {
  return new Promise(done => {
    setTimeout(() => {
      console.log(2);
      done()
    }, 1000);
  })
});
scheduler.schedule(function() {
  return new Promise(done => {
    setTimeout(() => {
      console.log(3);
      done()
    }, 3000);
  })
});
FZs
  • 16,581
  • 13
  • 41
  • 50
1

You would need a que for the timeouts, eg:

const scheduler = {
    done:function(){}, // Not sure what this function is supposed to do
    schedule:function(callback, timeout) {
        scheduler.que.push([callback, timeout]); // Add the function along with its wait time
        if(scheduler.que.length == 1) scheduler.startQue(); // If the que was previously empty, start the execution of the que
    },
    startQue() {
        setTimeout(() => {
            scheduler.que[0][0](); // run the callback timeout
            scheduler.que.shift(); // Remove the just ran timeout
            if(scheduler.que.length >= 1) scheduler.startQue(); // Start another timeout if we still have some in the que
        }, scheduler.que[0][1]);
    },
    que: []
};
scheduler.schedule(() => console.log(1), 2000); // Wait for 2 seconds to print
scheduler.schedule(() => console.log(2), 1000); // Wait 1 second after the first one printed
scheduler.schedule(() => console.log(3), 3000); // Wait another 3 seconds after the second one
Elias Schablowski
  • 2,619
  • 9
  • 19
  • you have changed the question, schedule supposed to take function as an input, not both function and it's corresponding timeout – Asutosh Jul 22 '20 at 09:44
-1

const scheduler = {
  done: function (cb) {
    cb();
    this.timeouts.shift();
    this.timeouts[0] && this.timeouts[0]();
  },
  schedule: function (cb, ms) {
    const timeout = () => setTimeout(this.done.bind(this), ms, cb);
    this.timeouts.push(timeout) == 1 && timeout();
  },
  timeouts: [],
};

scheduler.schedule(() => console.log('1'), 2000);
scheduler.schedule(() => console.log('2'), 1000);
scheduler.schedule(() => console.log('3'), 3000);
GirkovArpa
  • 4,427
  • 4
  • 14
  • 43
  • you have changed the question, schedule supposed to take function as an input, not both function and it's corresponding timeout – Asutosh Jul 22 '20 at 09:12
  • When I posted this answer your example was `scheduler.schedule(setTimeOut()=>{console.log(1)},2000);`, which is not even valid JavaScript, much less a "function and its timeout". If you want precise answers you need a precise question. – GirkovArpa Jul 22 '20 at 15:31
  • oops my bad. Sorry about that, the question should have been more precise and syntatically correct. – Asutosh Jul 23 '20 at 04:41