Reputation: 1285
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!
Upvotes: 9
Views: 37864
Reputation: 179
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);
Upvotes: 4
Reputation: 4764
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:
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()
Upvotes: 1
Reputation: 742
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
Upvotes: 0
Reputation: 318252
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);
Upvotes: 15
Reputation: 664650
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.
Upvotes: 7
Reputation: 324680
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
Upvotes: 3
Reputation: 150263
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.
Upvotes: 1