10

好的,我已经在这里和其他地方查看了关于 jquery/javascript 中的 setInterval 的几篇帖子,关于答案的恼人之处在于我没有了解解决方案为何有效。

请考虑:

使用匿名函数,我们可以设置警报以重复输出“兔子”:

setInterval(function(){
  alert("bunnies")
},3000);

但是如果我们想使用一个非匿名函数,我们必须编写代码

设置间隔(跳,3000);

其中功能:

function hop(){
    alert("bunnies");
}

如果我们尝试编码:

setInterval(hop(),3000);

hop 只执行一次。我不明白为什么会这样。我已经阅读了各种关于此的 SO,这意味着我们需要传递对 setInterval 的引用。这是否意味着第一种形式 setInterval(hop,3000); 通过引用传递。如果是这样,这可以解释吗?

因此我们有一个问题。显然,希望能够将参数传递给函数跳跃,如.....

setInterval(hop("bunnies"),3000);

其中功能:

function hop(msg){
    alert(msg);
}

这确实会导致调用 hop 并输出“bunnies”,但再次调用该函数仅一次。

因此,据我所知,将参数传递给由 setInterval 控制的函数的唯一方法是将其合并到匿名函数中:

setInterval(function(){
 hop("bunnies")
},3000);

这会传递参数并重复执行 hop,每 3 秒提醒我们注意兔子(注意兔子非常重要)。

因此问题:

  1. 这是唯一允许您传入参数的语法吗?
  2. 为什么 setInterval(hop("bunnies"),3000); 不行。
4

4 回答 4

16

setInterval期望一个函数作为第一个参数。当您尝试:

setInterval(function() {...}, 100);

或者

setInterval(funcName, 100);

您正确地传递了一个函数。

然而,当您尝试时setInterval(funcName(), 100);,您实际上是在调用该函数并将其返回值传递setInterval它是不正确的。

于 2012-10-15T11:51:16.873 回答
7

为什么不起作用setInterval(hop("bunnies"),3000);

setInterval(hop("bunnies"),3000);hop 立即调用,然后将其返回值( undefined) 传递给setInterval(将被忽略,因为它不是函数或字符串)。

这是唯一允许您传入参数的语法吗?

不,但它是最好的支持。

另一种语法是

 setInterval(hop, 3000, "bunnies")
于 2012-10-15T11:51:59.103 回答
6

1. 这是唯一允许您传入参数的语法吗?

是的,这是我能想到的唯一直接的方法......

setInterval(function(){
    hop("bunnies")
},3000);

...但当然,如果您必须处理很多间隔,您可以编写一个辅助函数,例如:

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

(试试看:http: //jsfiddle.net/ceHMs/

你会像这样使用它:

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

但是你必须评估这是否真的有必要。


2. 为什么不setInterval(hop("bunnies"),3000);工作。

这是因为 setInterval 需要对一个函数的引用,该函数应该每隔您指定的几毫秒执行一次。

括号是这里的关键。后跟括号的函数名会执行给定的函数并返回函数的结果,因此您不会传递对 setInterval 的引用,而是传递函数 hop('bunnies') 的返回值。函数的引用只是函数的名称。如果你想调用被引用的函数,只需在引用后面加上括号。简单的例子:

function executeFunction(fn){
    fn();
};

知道了这一点,我们实际上可以修改您的 hop 函数以使其工作setInterval(hop("bunnies"),3000);

function hop(msg){
    return function(){ alert(msg) }
}

但这与直接在 setInterval 调用中使用匿名函数几乎完全相同。现在您只需在调用 hop 时返回该匿名函数,这使您的 setIntervall 调用更短。

最后,它归结为您的个人喜好和特定用例。大多数情况下,直接在 setInterval 中使用匿名函数的方法是最明显的方法,也是最容易被其他人理解的方法。

于 2012-10-15T13:10:55.173 回答
1

您应该将函数作为变量传递,而不是调用它。

设置间隔(跳,3000);

因为第一个参数是一个按给定时间间隔调用的函数,所以通过将它像 hop() 一样放置,您调用该函数,而不是传递它。如果要传递参数,请使用函数包装器

setInterval(function(){hop(arguments)},3000);

于 2012-10-15T11:49:26.337 回答