Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setInterval using a non anonymous function requiring parameters has to be inside an anonymous function. Why?

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:

  1. Is this the only syntax that will allow you to pass a parameter in.
  2. Why does setInterval(hop("bunnies"),3000); not work.
like image 431
codepuppy Avatar asked Oct 15 '12 11:10

codepuppy


People also ask

How do you pass parameters to a function in setInterval?

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.

Why is it important to be careful with setInterval ()?

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.

How does the setInterval () function work in?

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() .

Why is it important to store the value returned by the call to setInterval ()?

setInterval returns an ID which you can later use to clearInterval(), that is to stop the scheduled action from being performed.


4 Answers

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")
like image 152
Quentin Avatar answered Oct 24 '22 23:10

Quentin


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.

like image 27
techfoobar Avatar answered Oct 25 '22 01:10

techfoobar


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);

like image 25
Roman Avatar answered Oct 24 '22 23:10

Roman


1. Is this the only syntax that will allow you to pass a parameter in?

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.


2. Why does 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.

like image 34
tsterker Avatar answered Oct 24 '22 23:10

tsterker