How can i stop a interval in javascript?
why does the interval not stop?
setInterval(alarm, 500);
window.clearInterval(alarm);
also tried:
window.setInterval(alarm, 500);
window.clearInterval(alarm);
always the same problem :(
still doesn't work:
var switc = 1;
getValue();
function getValue (){
if(switc == 1){
var myTimer = window.setInterval(alarm, 500);
}
else if(switc == 0){
window.clearInterval(myTimer);
}
}
function alarm(){
console.log("test");
}
When you call setInterval it returns a integer that you use to cancel the event. Store that into a variable and use that variable to cancel the event.
var myTimer = window.setInterval(alarm, 500);
window.clearInterval(myTimer);
EDIT:
Your code does not work since myTimer is a local variable and is reset every single time you call the function!
Make it global.
var myTimer = null;
function getValue (){
if(switc == 1){
myTimer = window.setInterval(alarm, 500);
}
...
MDN Docs: window.setInterval
Calls a function or executes a code snippet repeatedly, with a fixed time delay between each call to that function.
Syntax
var intervalID = window.setInterval(func, delay[, param1, param2, ...]);
var intervalID = window.setInterval(code, delay);
where
intervalID is a unique interval ID you can pass to clearInterval().
func is the function you want to be called repeatedly.
code in the alternate syntax, is a string of code you want to be executed repeatedly (using this syntax is not recommended for the same reasons as using eval())
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.
Note that passing additional parameters to the function in the first syntax does not work in Internet Explorer. If you want to enable this functionality on that browser you must use a compatibility code (see the Callback arguments paragraph).
That code evinces a misunderstanding of the API. The setInterval() function takes two arguments: a function to call, and a number representing the number of milliseconds between calls. The function returns a token (a number) that identifies that particular interval timer. The token can be passed to clearInterval() to cancel the timer.
You are tring to clear an non existent interval. Assign the id returned by setInterval() to an variable and use it in clearInterval().
In your case alarm is the function that executes and its not the intervals id
var interval = setInterval(alarm, 500);
clearInterval(interval);
var timer = setInterval(alarm, 500);
Window.clearInterval(timer);
function alarm() {
// Do stuff
}
You need to save the handle of the interval to a variable so you can reference it later when you want to clear/stop it.
Related
I want to call a function that could check an amount of time constantly using an interval within function that already works (running function) by interval.
That what I had did:
var interval;
var time = prompt("Insert amount of time in seconds");
function log ()
{
console.log ("log() called.");
}
function onrunning ()
{
interval = setInterval(log,time*1000);
}
gameloop = setInterval(onrunning,5);//This interval must not cleared
The first amount of time works fine but after that it's keep calling the log() function faster and faster till the browser crashes.
I tried to do this
var interval;
var time = prompt("Insert amount of time in seconds");
function log ()
{
console.log ("log() called.");
}
function onrunning ()
{
interval = setInterval(log,time*1000);
}
gameloop = setInterval(onrunning,5);
clearInterval(interval); //tried this but no differece.
You are clearing interval in a wrong place.
In your code, you are trying to clear it before it has been created (so it's basically a no-op).
You want to clear it after it has been created and executed:
function log ()
{
console.log ("log() called.");
clearInterval(interval);
}
You should also notice that since your onrunning is also fired as an "interval" callback, you are creating new log intervals on each callback execution frame. If you want to clear this interval too, just replicate the same logic as presented above, but inside onrunning callback.
I assume you want to fire the "log" callback ("onrunning" callback as well, probably) only once after a set period of time. In that case, you should use setTimeout instead of setInterval.
This has been already pointed out by Jaromanda X in this comment.
I have a flurry of interrupts coming into a handler and I don't want to service them until 5ms have passed since the last interrupt, indicating the flurry is over.
My thought was to call setTimeout(LookAtInterrupts, 5) each time the handler is entered, but I don't see in the setTimeout() documentation that it will cancel a pending scheduled call if it's called before that execution occurs.
Is that, in fact, what it will do? I don't want to get called 5ms after every handler interrupt, just the last one.
No, it won't - you can have as many pending timeouts as you want.
The function returns a key that you can use to cancel a timeout later:
var key = setTimeout( ... );
Then to cancel it later:
clearTimeout(key);
Calling clearTimeout() with an already-expired key is not an error, so you don't have to worry about synchronization problems.
setTimeout will not reset itself.
You can reset a timeout manually by
var timeout = setTimeout(...);
clearTimeout(timeout);
A setTimeout() won't cancel any previous timeouts implicitly.
However, you can achieve that by storing the identifier in a variable and clearing that each time.
var timeoutId = null;
var yourFn = function() {
clearTimeout(timeoutId);
timeoutId = setTimeout(fn, 5);
};
You need to store a reference. setTimeout result can be stored and cleared later on.
For a "resettable" setTimeout:
// first assign it
var timeout = setTimeout(function(){
foo();
}, 50);
// then look for an existing assignment before re-assinging
if (timeout) clearTimeout(timeout);
timeout = setTimeout(function(){
bar();
}, 50);
References:
setTimeout
clearTimeout
As an aside, be careful when setting a timeout < 5ms. Though HTML5 is supposed to support 4, I doubt you're actually getting anywhere close to that (w/ cost of spinning up the timeout).
Store reference to that setTimeout call in a variable, and after each successfull interrupt, before creating timeout, cancel the previous timeout,
var tv = null;
function interrupt(){
if(tv !== null){
clearTimeout(tv);
}
tv = setTimeout(LookAtInterrupts,5)
}
function LookAtInterrupts(){
}
By this, you'll guarantee that only the last interrupt will continue execution in 5ms intervals. I hope that was clear.
While you can implement this yourself, a more practical solution would be to grab underscore.js and use it's debounce function (see http://underscorejs.org/#debounce).
Then you can do:
var lookAtInterrupts = _.debounce(handleInterrupt, 5);
the resulting function will only run at most once every 5 ms.
When setTimeout() is executed it schedules one call to your binded function().
If you want to cancel it you have to get ID returned by setTimeout() and clear as:
var timeOutID = setTimeout( LookAtInterrupts, 5 );
(...)
clearTimeOut( timeOutID );
I am displaying a countdown watch with respect to a given endtime.
although its working perfect but i want to know which is best methods to apply.
below is my countdown function.
var timerId;
var postData = {endDate : endDate, tz : tz};
var countdown = function()
{
$.ajax({
type : 'post',
async : false,
timeout : 1000,
url : './ajax_countdown.php',
data : $.param(postData),
dataType : 'json',
success : function (resp){
$('#currentTime').html(resp.remainingTime);
}
});
}
what i want is that function (countdown) shoud be called automatically after every 1 second and if it does not execute/completed within 1 second then cancel the current ajax and start a new ajax call.
now I found there are 4 working methods
method 1: using setInterval() with window object
window.setInterval(countdown, 1000);
method 2 : using setInterval() independently
setInterval(function() {countdown()}, 1000);
method 3 : using setTimeOut inside the function an call other function to intialize main function
var countdown = function() {
$.ajax({ //ajax code });
timerId = setTimeout(countdown, 5000); // assign to a variable
}
function clockStart() {
if (timerId) return
countdown();
}
clockStart(); // calling this function
method 4 : using anonymous function call
var countdown = function() {
$.ajax({ //ajax code });
timerId = setTimeout(countdown, 5000);
}
(function(){
if (timerId) return;
countdown();
})();
Please tell me
What is con and pro of each method and which one is best/right method?
Should i use clearTimeOut() or clearInterval() ?
References
http://javascript.info/tutorial/settimeout-setinterval
Calling a function every 60 seconds
http://www.electrictoolbox.com/using-settimeout-javascript/
I wouldn't use any of your methods. The reason is setTimeout and setInterval do not guarantee that your code will execute after the specified delay. This is because JavaScript is single threaded.
If I need to call a function only once after a specified delay then I use setTimeout. However if I need to call a function after a fixed interval of time then I do not use setInterval. Instead I make use of delta timing. Here's the code.
The advantage of using delta timing is that your code will execute closer to the fixed interval of time you specify. It corrects itself. Creating and using a delta timer is simple. For example your code would be written as follows:
var timer = new DeltaTimer(function (time) {
$.ajax({
// properties
});
if (time - start >= 5000) timer.stop();
}, 1000);
var start = timer.start();
The above delta timer is better than setInterval (method 1), makes use of setTimeout (method 2) but also corrects itself, starts the timer using a function (method 3), and doesn't pollute the scope with a special clockStart function (method 4).
In addition you can easily get the exact time the function is called after the timer starts as the time the function is called is passed as an argument to the function. The timer also has a stop method to stop the timer. To start it again call start again.
Edit:
If you want to make the DeltaTimer look more like setInterval (start the timer automatically) you may implement a spawn function as follows:
DeltaTimer.spawn = function (render, interval) {
var timer = new DeltaTimer(render, interval);
var start = timer.start = function (start) {
return function () {
render.start = start();
};
}(timer.start);
start();
return timer;
};
Then you may automatically create and start the DeltaTimer as follows:
var timer = DeltaTimer.spawn(function countdown(time) {
$.ajax({
// properties
});
if (time - countdown.start >= 5000) timer.stop();
}, 1000);
Thus var timer = DeltaTimer.spawn(funct, delay); is equivalent to var interval = setInterval(funct, delay); and timer.stop(); is equivalent to clearInterval(interval);. I guess that's as much as you can automate it.
The benefit of using #1 over #2 is that the window reference removes the chance of a scope variable overwriting setInterval.
// When out of global scope...
function setInterval() {
}
window.setInterval(foo, 100); // still calls the "correct" setInterval
There's no difference between wrapping the call to countdown in a function (#1, #2). #2 gives you greater flexibility as you can also call other functions/ pass arguments etc (although it's obviously trivial to swap from #1 to #2 if this becomes the case).
#4 saves you having to declare a function clockStart, other than that, it's the same as #3.
Use clearTimeout if you used setTimeout, and clearInterval if you used setInterval...
You should also be aware of how setTimeout and setInterval work differently. There's an amazing answer here which explains that...
As for what I'd use? I'd use #2.
if you are creating countdown then why u don't use jquery plugin and customize it according to your requirements? Checkout here
http://www.tripwiremagazine.com/2012/05/jquery-countdown-scripts.html
I use setInterval to run a function (doing AJAX stuff) every few seconds. However I also have an other function also calling it.
setInterval(myFunc(), 5000);
function buttonClick() {
// do some stuff
myFunc();
}
Most of the time it works, however sometimes this function gets called twice at the same time resulting in receiving exactly the same result twice, something I don't want.
I think I have to use clearTimeout:
var interval = setInterval(myFunc(), 5000);
function buttonClick() {
clearTImeout(interval);
// do some stuff
myFunc();
interval = setInterval(myFunc(), 5000);
}
However this causes the function to halt. Since it gets called from an other function some code never gets executed. How can I prevent this?
however sometimes this function gets called twice at the same time resulting in receiving exactly the same result twice, something I don't want.
JavaScript on browsers is single-threaded (barring using the new web workers stuff, but that wouldn't apply here anyway). Your function will never get called while it's running. (But more below.)
In your various code quotes, you're calling myFunc where you mean to just be referring to it. E.g.:
var interval = setInterval(myFunc(), 5000);
should be
var interval = setInterval(myFunc, 5000);
// ^--- No parentheses
Your code cancelling the timeout will work if you correct that:
var interval = setInterval(myFunc, 5000);
function buttonClick() {
clearTImeout(interval);
// do some stuff
myFunc();
interval = setInterval(myFunc, 5000);
}
But there's no reason to do that, myFunc cannot get called while it's running anyway.
If myFunc is triggering something that will complete asynchronously (an ajax call, for instance), the above won't help (for the simple reason that myFunc will start the process and then return; the process will complete separately). In that situation, your best bet is to have myFunc schedule its next call itself:
function myFunc() {
// Do my work...
// Schedule my next run
setTimeout(myFunc, 5000);
}
...and not use setInterval at all.
I realize there's a couple of solutions already, but thought I'd show one that has a tad more than just "do this". I tend to learn by example, and thought I would extend the same practice. That being said, the demo is here but I'll try to explain as well.
// Here we assign the function to a variable that we can use as an argument to the
// setInterval method.
var work = function(){
// performing a very simple action for the sake of demo
$('#log').append('Executed.<br />');
};
// this is a variable that is essentially used to track if the interval is or is
// not already running. Before we start it, we check it. Before we end it, we also
// check it. Let's start off with it started though
var worker = setInterval(work, 5000);
// bind to the start button
$('#start').click(function(){
// Test: is the worker already running?
if (worker)
// Yes it is, don't try to call it again
$('#warn').text('Timer already running!');
else{
// no it's not, let's start it up using that function variable we declared
// earlier
worker = setInterval(work,3000);
$('#warn').text('Started!');
}
});
// bind to the stop button
$('#stop').click(function(){
// test: is the worker running?
if (!worker)
// no, so we can't stop it
$('#warn').text('Timer not running!');
else{
// yes it's working. Let's stop it and clear the variable.
clearInterval(worker);
worker = null;
$('#warn').text('Stopped.');
}
});
Unless myFunc returns a function I would do this (also use clearInterval in stead of clearTimeout):
var interval = setInterval(myFunc, 5000);
function buttonClick() {
clearInterval(interval);
// do some stuff
myFunc();
interval = setInterval(myFunc, 5000);
}
setInterval expects a function in its argument. You call a function by using myFunc(). so whatever is returned by myFunc was passed to setInterval which is probably not what you want.
my problem is that I can not stop a timer.
I had this method to set a timeout from this forum.
It supposed to store the identifyer in the global variable.
By accident, I found out that it is still running after I hide "mydiv".
I also need to know now, if the recursive function creates multiple instances or just one for the timeouts. Because first I thought that it overwrites "var mytimer" everytime.
Now I am not so sure.
What would be a solid way to stop the timer??
var updatetimer= function () {
//do stuff
setTimeout(function (){updatetimer();}, 10000);
}//end function
//this should start and stop the timer
$("#mybutton").click(function(e) {
e.preventDefault();
if($('#mydiv').is(':visible')){
$('#mydiv').fadeOut('normal');
clearTimeout(updatetimer);
}else{
$('#mydiv').fadeIn('normal');
updatetimer();
}
});
thanks, Richard
I think that most people are getting at the reason why this isn't working, but I thought I would provide you with updated code. It is pretty much the same as yours, except that it assigns the timeout to a variable so that it can be cleared.
Also, the anonymous function in a setTimeout is great, if you want to run logic inline, change the value of 'this' inside the function, or pass parameters into a function. If you just want to call a function, it is sufficient to pass the name of the function as the first parameter.
var timer = null;
var updatetimer = function () {
//do stuff
// By the way, can just pass in the function name instead of an anonymous
// function unless if you want to pass parameters or change the value of 'this'
timer = setTimeout(updatetimer, 10000);
};
//this should start and stop the timer
$("#mybutton").click(function(e) {
e.preventDefault();
if($('#mydiv').is(':visible')){
$('#mydiv').fadeOut('normal');
clearTimeout(timer); // Since the timeout is assigned to a variable, we can successfully clear it now
} else{
$('#mydiv').fadeIn('normal');
updatetimer();
}
});
I think you misunderstand 'setTimeout' and 'clearTimeout'.
If you want to set a timer that you want to cancel later, do something like:
foo = setTimeout(function, time);
then call
clearTimeout(foo);
if you want to cancel that timer.
Hope this helps!
As written mytimer is a function which never has the value of a timeout identifier, therefore your clearTimeout statement will achieve nothing.
I don't see any recursion here at all, but you need to store the value setTimeout returns you, and if you need to pair this with multiple potential events you need to store it against a key value you can lookup - something like an element id perhaps?
This is a simple pseudocode for controlling and conditioning recursive setTimeout functions.
const myVar = setTimeout(function myIdentifier() {
// some code
if (condition) {
clearTimeout(myIdentifier)
} else {
setTimeout(myIdentifier, delay); //delay is a value in ms.
}
}, delay);
You can not stop all the functions that are created, intead of that convert the function to setInterval (represent the same logic that your recursive function) and stop it:
// recursive
var timer= function () {
// do stuff
setTimeout(function (){timer();}, 10000);
}
The same logic using setInterval:
// same logic executing stuff in 10 seconds loop
var timer = setInterval(function(){// do stuff}, 10000)
Stop it:
clearInterval(timer);
As noted above, the main reason why this code isn't working is that you're passingt he wrong thing into the clearTimeout call - you need to store the return value of the setTimeout call you make in updateFunction and pass this into clearTimeout, instead of the function reference itself.
As a second suggestion for improvement - whenever you have what you call a recursive timeout function, you would be better off using the setInterval method, which runs a function at regular intervals until cancelled. This will achieve the same thing you're trying to do with your updateFunction method, but it's cleaner as you only need to include the "do stuff" logic in the deferred function, and it's probably more performant as you won't be creating nested closures. Plus it's The Right way to do it which has got to count for something, right? :-)
(function(){
$('#my_div').css('background-color', 'red');
$('#my_div').hover(function(){
var id=setTimeout(function() {
$('#my_div').css('background-color', 'green');
}, 2000);
var id=setTimeout(function() {
$('#my_div').css('background-color', 'blue');
}, 4000);
var id=setTimeout(function() {
$('#my_div').css('background-color', 'pink');
}, 6000);
})
$("#my_div").click(function(){
clearTimeout(id);
})
})();