Reputation: 521
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?
Upvotes: 1
Views: 2718
Reputation: 8141
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.
Upvotes: 0
Reputation: 101614
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.');
}
});
Upvotes: 0
Reputation: 1074385
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.
Upvotes: 2