9

I want to change setInterval function time when my code is running.

I try this

<script type="text/javascript">
        $(function () {
            var timer;
            function come() { alert("here"); }
            timer = setInterval(come, 0);
            clearInterval(timer);
            timer = setInterval(come, 10000);
        });
    </script>

First SetInterval does not work!

BenMorel
  • 34,448
  • 50
  • 182
  • 322
altandogan
  • 1,245
  • 6
  • 21
  • 44

7 Answers7

15

You're clearing the interval on the next line, so the first one wont work, as it gets cleared right away :

        timer = setInterval(come, 0);
        clearInterval(timer);
        timer = setInterval(come, 10000);

Also, as gdoron says, setting a interval of nothing isn't really valid, and not a really good idea either, use setTimeout instead, or just run the function outright if no delay is needed.

        come();
        clearInterval(timer);
        timer = setInterval(come, 10000);
BenMorel
  • 34,448
  • 50
  • 182
  • 322
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • while using the above code the come() function stops one second and runs again... is there any way to avoid the stop of come function?.... – Naveen K Nov 08 '13 at 09:49
7

You can't. You will need to use setTimeout, and call it repetitively:

var timer; // current timeout id to clear
function come(){ /* do something */};
var time; // dynamic interval

(function repeat() {
    come();
    timer = setTimeout(repeat, time);
})();

With this you can set a different "interval" to be applied each time the function repeat is executed. Yet, nothing changes if alter time during a timeout, you'd need to stop the timeout for that.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 1
    Where does `timer` come in the game? – gdoron May 13 '12 at 23:52
  • Thanks, this is what I needed. Maybe you can add, that you can abort the loop with `clearTimeout(timer);` within `come();` – Sonic750 Jul 10 '16 at 16:50
  • @Sonic750: If you want to terminate the loop, returning a boolean from `come` and putting an `if`-condition around the `setTimeout` call. Or you check whether `timer` is infinite… – Bergi Jul 10 '16 at 16:52
3

I know this is an old post, but I have implemented a typescript version for changing the interval in run time:

class LoopTimer {
  private timer: null | NodeJS.Timer;
  private callback: (...args: any[]) => void;
  private ms: number;
  private started: boolean;

  constructor(callback: (...args: any[]) => void, ms: number) {
    this.callback = callback;
    this.ms = ms;
    this.timer = null;
    this.started = false;
  }

  start() {
    if (!this.started) {
      this.timer = setInterval(this.callback, this.ms);
      this.started = true;
    }
  }

  stop() {
    if (this.timer) {
      clearInterval(this.timer);
      this.timer = null;
      this.started = false;
    }
  }

  get getStarted(): boolean {
    return this.started;
  }

  setInterval(ms: number) {
    this.ms = ms;
    if (this.started) {
      this.stop();
      this.start();
    }
  }
}

You can use it like this: The timer will stop and start again when interval is changed.

 const myTimer = new LoopTimer(()=>{
        console.log("Hello");
    }, 100);
    
myTimer.setInterval(500);
Elvin Chu
  • 150
  • 1
  • 8
2

There is no way to directly change the interval at which a function fires. The best you can do is cancel an interval and set a new one with the same function and updated timer. Here's a possible way of doing it:

timer = {
    timers:{},
    inc:0,
    start:function(cb,gap) {
        var key = inc;
        inc++;
        timer.timers[key] = [setInterval(cb,gap),cb];
        return key;
    },
    stop:function(id) {
        if( !timer.timers[id]) return;
        clearInterval(timer.timers[id][0]);
        delete timer.timers[id];
    },
    change:function(id,newgap) {
        if( !timer.timers[id]) return;
        clearInterval(timer.timers[id][0]);
        setInterval(timer.timers[id][1],newgap);
    }
};

Usage:

var myTimer = timer.start(function() {....},1000);
// calls every second

timer.change(myTimer,5000);
// now calls every five seconds
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
1
timer = setInterval(come, 0); // zero isn't a valid interval...

You probably wants:

come();
timer = setInterval(come, 10000);

docs on MDN:

delay is the number of milliseconds (thousandths of a second) that the setInterval() function should wait before each call to func. As with setTimeout, there is a minimum delay enforced.

And:

Historically browsers implement setTimeout() "clamping": successive setTimeout() calls with delay smaller than the "minimum delay" limit are forced to the use at least the minimum delay. The minimum delay, DOM_MIN_TIMEOUT_VALUE, is 4 ms (stored in a preference in Firefox: dom.min_timeout_value), with a DOM_CLAMP_TIMEOUT_NESTING_LEVEL of 5ms.

gdoron
  • 147,333
  • 58
  • 291
  • 367
1

this is mi example, i think is more simple and easy to understand

const timer = {
  time: 5, // 5 time in seconds
  _time: null,
  _timeout: null,
  fun: () => {},
  start() {
    if (this._timeout == null) {
      const self = this;
      this.fun();
      this._timeout = setTimeout(function repeater() {
        self.fun();
        self._timeout = setTimeout(repeater, 1000 * self.time);
      }, 1000 * this.time);
    }
  },
  stop() {
    const timeout = this._timeout;
    this._timeout = null;
    this.set_time(); // set time to default
    clearTimeout(timeout);
  },
  set_time(time) {
    if (this._time == null) this._time = this.time;

    if (time) {
      this.time = time;
    } else {
      this.time = this._time;
    }
  },
};

Explication:

  • time: is the time of interval between every iteration, cycle or next call
  • _time: this variable save the default value of time, when use stop(), this variable(_time) restore "time"
  • start: this function start the iteration, if you call again, it will not duplicate.
  • stop: this function, stop the timeout and set default time and _timeout
  • set_time: this function set a new value to time, if you not send a parameter, time restore to default value, declare on running in this example is "5"

example:

const timer = {
      time: 5, // 5 time in seconds
      _time: null,
      _timeout: null,
      fun: () => {},
      start() {
        if (this._timeout == null) {
          const self = this;
          this.fun();
          this._timeout = setTimeout(function repeater() {
            self.fun();
            self._timeout = setTimeout(repeater, 1000 * self.time);
          }, 1000 * this.time);
        }
      },
      stop() {
        const timeout = this._timeout;
        this._timeout = null;
        this.set_time(); // set time to default
        clearTimeout(timeout);
      },
      set_time(time) {
        if (this._time == null) this._time = this.time;
    
        if (time) {
          this.time = time;
        } else {
          this.time = this._time;
        }
      },
    };
    
// print time
timer.fun = () =>{
    console.log(new Date())
};
timer.set_time(10)
timer.start()
DarckBlezzer
  • 4,578
  • 1
  • 41
  • 51
0

I know this post is old, but i needed something similar, maybe someone needs it.

This is a version without setInterval, based on the code from the other reaction (Niet the Dark Absol).

function timer()
{
    var timer = {
        running: false,
        iv: 5000,
        timeout: false,
        cb : function(){},
        start : function(cb,iv,sd){
            var elm = this;
            clearInterval(this.timeout);
            this.running = true;
            if(cb) this.cb = cb;
            if(iv) this.iv = iv;
            if(sd) elm.execute(elm);
            this.timeout = setTimeout(function(){elm.execute(elm)}, this.iv);
        },
        execute : function(e){
            if(!e.running) return false;
            e.cb();
            e.start();
        },
        stop : function(){
            this.running = false;
        },
        set_interval : function(iv){
            clearInterval(this.timeout);
            this.start(false, iv);
        }
    };
    return timer;
}

Usage:

var timer_1 = new timer();
timer_1.start(function(){
    //magic here
}, 2000, false);

var timer_2 = new timer();
timer_2.start(function(){
    //more magic here
}, 3000, true);

//change the interval
timer_2.set_interval(4000);

//stop the timer
timer_1.stop();

The last parameter of the start function is a boolean if the function needs to be run at 0.

You can also find the script here: https://github.com/Atticweb/smart-interval

Jaapze
  • 732
  • 6
  • 15