Ok I have reviewed several postings here and elsewhere regarding setInterval in jquery/javascript the annoying thing about the answers is that I am not learning why the solutions work.
Please consider:
Using an anonymous function we can set an alert to repeatedly output "bunnies":
setInterval(function(){
alert("bunnies")
},3000);
But if we want to use a non anonymous function we have to code
setInterval(hop,3000);
where funct:
function hop(){
alert("bunnies");
}
If we attempt to code:
setInterval(hop(),3000);
hop is executed but once only. I do not understand why this is. I have read various SO's on this which imply that we need to be passing a reference to setInterval. Does this imply that the first form setInterval(hop,3000); passes by reference. If so could this be explained?
Therefore we have an issue. In that obviously it would be desireable to be able to pass a parameter to function hop like .....
setInterval(hop("bunnies"),3000);
where funct:
function hop(msg){
alert(msg);
}
This does cause hop to be invoked and "bunnies" to be output but again the function is invoked once only.
So as far as I can work out the only way to pass a parameter to a function being controlled by setInterval is to incorporate it inside an anonymous function:
setInterval(function(){
hop("bunnies")
},3000);
this passes the parameter and repeats the execution of hop alerting us to bunnies every 3 seconds (very important to be alert to bunnies).
Questions therefore:
The setInterval() method can pass additional parameters to the function, as shown in the example below. setInterval(function, milliseconds, parameter1, parameter2, parameter3); The ID value returned by setInterval() is used as the parameter for the clearInterval() method.
Also, if any error occurs in setInterval code block, it will not stop execution but keeps on running faulty code. Not to mention they need a clearInterval function to stop it. Alternatively, you can use setTimeout recursively in case of time sensitive operations.
The setInterval() method, offered on the Window and Worker interfaces, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. This method returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval() .
setInterval returns an ID which you can later use to clearInterval(), that is to stop the scheduled action from being performed.
Why does
setInterval(hop("bunnies"),3000);
not work.
setInterval(hop("bunnies"),3000);
will call hop
immediately and then pass its return value (undefined
) to setInterval
(where it will be ignored because it isn't a function or a string).
Is this the only syntax that will allow you to pass a parameter in.
No, but it is the best supported.
The other syntax is
setInterval(hop, 3000, "bunnies")
setInterval
expects a function as the first parameter. When you attempt:
setInterval(function() {...}, 100);
or
setInterval(funcName, 100);
you are correctly passing a function.
Whereas, when you attempt setInterval(funcName(), 100);
, you are actually calling the function and passing its return value to setInterval
which is incorrect.
you should pass a function as variable not call it.
setInterval(hop,3000);
Because the first parameter is a function to call by given interval, by putting it like hop() you call the function, not passing it. If you want to pass an arguments use function wrapper
setInterval(function(){hop(arguments)},3000);
Yes, this is the only straight forward way I could think of...
setInterval(function(){
hop("bunnies")
},3000);
... but of course you could write a helper function if you have to handle a lot of intervals, something like:
function Looper() {
this.loops = {};
this.start = function(name, fn, interval, params) {
this.loops[name] = setInterval(function() {
fn.apply(null, params); // maybe bind the function?
}, interval);
};
this.stop = function(name) {
clearInterval(this.loops[name]);
};
}
(try it: http://jsfiddle.net/ceHMs/)
And you would use it like this:
function say(name, msg){ console.log(name,':',msg) };
function shout(name, msg){ console.log(name,':',msg.toUpperCase()) };
var looper = new Looper();
looper.start('say', say, 1000, ['clock' 'tick']);
looper.start('shout', shout, 2000, ['clock' 'tack']);
// ... later ...
looper.stop('shout');
But you have to evaluate if this really is necessary.
setInterval(hop("bunnies"),3000);
not work.This is because setInterval expects a reference to a Function that should be executed every few milliseconds that you specify.
The parenthesis are the key here. A function name followed by parenthesis does execute the given function and returns the result of the function and therefore you would not pass a reference to setInterval but the return value of the function hop('bunnies'). A reference of a function is simply the name of the function. And if you want to call the referenced function, just append parenthesis to the reference. Trivial example:
function executeFunction(fn){
fn();
};
Knowing this we could actually modify your hop function to make it work with setInterval(hop("bunnies"),3000);
:
function hop(msg){
return function(){ alert(msg) }
}
But this is almost exactly the same as using an anonymous function directly in the setInterval call. Now you just return that anonymous function when calling hop, wich makes you setIntervall call shorter.
In the end it boils down to your personal preferences and the specific use case. Most of the times the approach with an anonymous function directly in your setInterval is the most obvious one and the easiest for others to understand.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With