0

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,

5
  • Please tell us why var fn2 is not executed? You can't tell if this function will ever be called again Commented May 22, 2017 at 5:29
  • @Justinas - it is executed ... see fn2() - that executes it Commented May 22, 2017 at 5:29
  • But fn1 and fn3 is not called again. You do not assign function, you assign value of function return. So what is the logic? Commented May 22, 2017 at 5:32
  • 1
    @Justinas funQueue return a handler to cancel the execution Commented May 22, 2017 at 5:33
  • You say "queue", but the functions aren't really queued up after each other, are they? They each have an independently specified run time that could be in any order? You don't want funQueue() to take a function as an argument, and execute that function after the specified delay? (You just want it to display a string message?) Commented May 22, 2017 at 5:41

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

10 Comments

Nice. I think here setTimeout creates multiple instances of it, can we do it in way that we can have only one instance of setTimeout
Calling setTimeout() schedules a single timeout. You need one timeout per message, because each message has its own delay and needs to be independently cancellable. Click the "Run code snippet" button and see the result for yourself.
I mean, if I call funQueue three times,then 3 timers will be started right?
Yes. But as I said, you need that because each call to funQueue() specifies its own time. I'm not sure how else you think it could work.
can we have one timer to pickup these messages. something like storing all string messages in one array and letting timer to pickup the string message that should fire next.
|
0

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
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.