flex
flex

Reputation: 185

Function queue based on time

I want implement function queue,where it should be executed based upon passed in time delay. If any of the function in the queue is invoked before the delay, then queue must not execute that function and should be moved to the next function in the queue.

For example:

function funQueue(message,date){

  //logic
}

var fn1=funQueue("message1",new Date().getTime()+500)
var fn2=funQueue("message2",new Date().getTime()+1000)
var fn3=funQueue("message3",new Date().getTime()+2000)
    fn2()

When it is executed like the above it should print.

message1

message3

please note message2 is not printed.

Thanks all,

Upvotes: 0

Views: 385

Answers (2)

nnnnnn
nnnnnn

Reputation: 150050

Maybe a little something like the following, using setTimeout() and clearTimeout():

function funQueue(message,date){
  var timeoutId = setTimeout(function() {  // schedule a timeout
    console.log(message)                   // that logs the message
  }, date - new Date().getTime())          // at the specified time
  
  return function() {                      // return a function
    clearTimeout(timeoutId)                // that cancels the timeout
  }
}

var fn1=funQueue("message1",new Date().getTime()+500)
var fn2=funQueue("message2",new Date().getTime()+1000)
var fn3=funQueue("message3",new Date().getTime()+2000)
fn2()

Note that if you call funQueue() with a time that is in the past it will still call setTimeout(), which means the message would be logged immediately after the current code completes unless it is cancelled within the current code.

EDIT: I was asked in a comment to implement it without multiple simultaneous timeouts. The following is the first way that came to mind. I'm sure this could be tidied up, optimised, and/or completely rewritten in a better way, but it worked the first time I clicked "run" so I think it's a good enough starting place. I'll leave the explanation of how it works as an exercise for the reader...

var funQueue = function() {
  var queue = []
  var timeoutId
  function setNext() {
    clearTimeout(timeoutId)
    if (queue.length > 0) {
      timeoutId = setTimeout(function() {
        console.log(queue.shift().message)
        setNext()
      }, queue[0].date - new Date().getTime())
    }
  }  
  return function(message,date){
    var item = { message: message, date: date }
    var i = 0
    while (i < queue.length && date >= queue[i].date) i++
    queue.splice(i, 0, item)
    setNext()
    return function() {  
      var i = queue.indexOf(item)
      if (i != -1) {
        queue.splice(i, 1)
        setNext()
      }
    }
  }
}()

var fn1=funQueue("message1",new Date().getTime()+500)
var fn2=funQueue("message2",new Date().getTime()+1000)
var fn3=funQueue("message3",new Date().getTime()+2000)
var fn4=funQueue("message4",new Date().getTime()+1500)
var fn5=funQueue("message5",new Date().getTime()+2000)
fn2()

Upvotes: 2

Merunas Grincalaitis
Merunas Grincalaitis

Reputation: 859

Do something like this to check whether the time has passed or not

var timePassed;
function funQueue(message, date){
  if(timePassed > date){
     timePassed = new Date.getTime();
     // Do stuff
  }
}

Upvotes: 0

Related Questions