Skip to content Skip to sidebar Skip to footer

Javascript Timing: How Do I Execute A Function Every 5, 7, And 8 Seconds?

Let's say I have a function log() var log = function(i) { console.log('Executing at time: ' + i); } And I want to execute log() on an interval, every x, y, and z seconds? Let'

Solution 1:

You can use the function "setInterval". Here is a example:

var interval1Id = setInterval(function(){
    console.log("logging every 5 seconds");
},5000);

var interval2Id = setInterval(function(){
    console.log("logging every 7 seconds");
},7000);

var interval3Id = setInterval(function(){
   console.log("logging every 8 seconds");
},8000);

Variables "intervalXId" are saved just in case you want to stop any interval.


Solution 2:

The easy solution is to set a timer function that's called every second and keeps a count of how many seconds have elapsed; if the count is a multiple of 5, 7, or 8, the timer function calls the function you want to execute.


Solution 3:

Borrowing from ZER0's idea, I would set up a recursive timeout chain similar to this --

function startTimeoutChain() { //Represents 1 loop cyele

setTimeout(function() {
  log(x);
  setTimeout(function() {
    log(y);
    setTimeout(function() {
      log(z);
      startTimeoutChain(); // Begin next loop
    }, 1000);
  }, 2000);
}, 5000);

}

Just call that once & you should have something that is pretty robust. Even if the clock drifts, these values will be calibrated to each other because they are done with the delta of the times, essentially.

Though to be honest, I'm having a hard time understanding if you want to call these on the 5th, 7th, 8th seconds of some loop cycle or simply every 5, 7, 8 seconds independently of some master loop.


Solution 4:

You need to set the next timeout inside the previous one:

// x is at 5 seconds, run 5000 milliseconds after the start
setTimeout(function() {
  log(x);
  setTimeout(function() {
    log(y);
    setTimeout(function() {
      log(z);
    }, 1000);
  }, 2000);

}, 5000);

In this way you don't schedule up front all the timeouts, but just one at the time, and there is less error's margin (the second timeout will start after the first is ending, and so on.

Edit I missed actually that the OP wanted this repeated. In this case, you just need to have the first function expression with a name instead of an anonymous one, and call it at the end:

setTimeout(function entry() {
   log(x);
   setTimeout(function() {
     log(y);
     setTimeout(function() {
       log(z);
       setTimeout(entry, 5000);
     }, 1000);
   }, 2000);
 }, 5000);

My comment was about to avoid to nest, so you could have a promise-like approach. Notice that it's also possible doing that with an additional function as jm0 made, however is an additional pollution of the scope, where using function expression avoid that.


Solution 5:

hmmm a naive solution could be like this. With jQuery though if you have only these three intervals a nice solution would be to use deferrds.

function log (val) {
    console.log(val);
}

var intervals = [{interval: 5000, logVal: 'x', logged: false},
                 {interval: 7000, logVal: 'y', logged: false},
                 {interval: 8000, logVal: 'z', logged: false}];

var startTime;

function myLog () {
    var endTime = new Date().getTime();
    var diff = endTime - startTime;

    for (var i = 0; i < (intervals.length - 1); i++) {
        if (diff >= intervals[i].interval && diff < intervals[i+1].interval && !intervals[i].logged) {
            log(intervals[i].logVal);
            intervals[i].logged = true;
        }
    }

    // for last interval
    if (diff >= intervals[i].interval) {
        log(intervals[i].logVal);
        startTime = new Date().getTime();
        return;
    }

    // Reset Time and run again
    setTimeout(myLog, 500);
}

startTime = new Date().getTime();
setTimeout(myLog, 1000);

here's the fiddle http://jsfiddle.net/jD8zn/4/


Post a Comment for "Javascript Timing: How Do I Execute A Function Every 5, 7, And 8 Seconds?"