javascript setInterval() 只运行一次函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8732191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
setInterval() only running function once
提问by James Dawson
I want to periodically query a PHP script for new messages. To do so, I'm using the setInterval() function and AJAX.
我想定期查询新消息的 PHP 脚本。为此,我使用了 setInterval() 函数和 AJAX。
$(document).ready(function(){
var queryInterval = 1000; /* How fast we query for new messages */
setInterval(getMessages(), queryInterval);
function getMessages() {
console.log("tick");
}
});
However, when I look at the Javascript console, I'm only seeing "tick" once. I've made sure that the console doesn't ignore any more logs of the same strings, so if the code was working properly it should show "tick" in the console every second.
但是,当我查看 Javascript 控制台时,我只看到“滴答”一次。我已经确保控制台不会再忽略相同字符串的更多日志,所以如果代码运行正常,它应该每秒在控制台中显示“滴答”。
Anyone know what could be going wrong here?
有谁知道这里可能出了什么问题?
回答by qwertymk
Change:
改变:
setInterval(getMessages(), queryInterval);
To:
到:
setInterval(getMessages, queryInterval);
回答by Wayne
Actually, setInterval
isn't running getMessages
at all (not even once). setInterval
expects a referenceto a function, but you're executing the getMessages
function immediatelyand passing its return value to setInterval
(which is undefined
). That's what the parens after getMessage
do.
实际上,setInterval
根本没有运行getMessages
(甚至一次)。setInterval
期望对函数的引用,但您正在立即执行该getMessages
函数并将其返回值传递给(即)。这就是后面的括号所做的。setInterval
undefined
getMessage
Pass a reference to setInterval
like this:
setInterval
像这样传递一个引用:
setInterval(getMessages, queryInterval);
If this is the only place that getMessages
is used, then you could also write it like this:
如果这是唯一使用的地方getMessages
,那么你也可以这样写:
setInterval(function() {
console.log("tick");
}, queryInterval);
回答by nav
Remove the ()
after getMessage
删除()
后getMessage
回答by Tim Medora
This callsgetMessages
, not schedules it. Remove the parenthesis.
这会调用getMessages
,而不是安排它。去掉括号。
setInterval(getMessages(), queryInterval);
setInterval(getMessages, queryInterval);
回答by David Edwards
Although others have already covered this ground above, both window.setTimeout() and window.setInterval() require function references. Your code provides, instead, the return valuefrom a function invocation.
尽管其他人已经在上面介绍了这一点,但 window.setTimeout() 和 window.setInterval() 都需要函数引用。相反,您的代码提供了函数调用的返回值。
When you wish to call, or invoke, a JavaScript function, you write, as expected:
当您希望调用或调用 JavaScript 函数时,您可以按预期编写:
DoMyfunction();
DoMyfunction();
The JavaScript engine will execute that function upon encountering that line.
JavaScript 引擎将在遇到该行时执行该函数。
However, what setTimeout() and setInterval() require, is a reference to the function objectcorresponding to your function. Which you obtain via the following, and similar means:
但是, setTimeout() 和 setInterval() 需要的是对与您的函数相对应的函数对象的引用。您通过以下方式获得,以及类似的方式:
myFunc = DoMyFunction;
myFunc = DoMyFunction;
That line copies a reference to the function objectcorresponding to DoMyFunction() into a new variable. Which you can then pass to setInterval() and setTimeout(), viz:
该行将对与 DoMyFunction() 对应的函数对象的引用复制到一个新变量中。然后您可以将其传递给 setInterval() 和 setTimeout(),即:
discard = window.setTimeout(myFunc, 1000);
丢弃 = window.setTimeout(myFunc, 1000);
That line above will direct the JavaScript engine to execute your intended function (namely DoMyFunction()) once, after 1 second has elapsed, and:
上面那一行将指示 JavaScript 引擎在 1 秒后执行您想要的函数(即 DoMyFunction())一次,并且:
discard = window.setInterval(myFunc, 1000);
丢弃 = window.setInterval(myFunc, 1000);
will direct the JavaScript engine to execute your intended function repeatedly, once every second.
将指示 JavaScript 引擎重复执行您的预期功能,每秒一次。
You could, of course, achieve the same effect, without using a new variable, simply as follows:
当然,您可以在不使用新变量的情况下实现相同的效果,如下所示:
discard = window.setTimeout(DoMyFunction, 1000);
丢弃 = window.setTimeout(DoMyFunction, 1000);
etc.
等等。
If, however, you make the mistake of using:
但是,如果您错误地使用了:
discard = window.setTimeout(DoMyFunction(), 1000);
丢弃 = window.setTimeout(DoMyFunction(), 1000);
what happens instead is that DoMyFunction() is executed, and any return parameter arising therefrom is thenpassed to the window.setTimeout() function. Since window.setTimeout() is expecting a function object reference to be passed here, and instead receives whatever your function returns (or undefinedif your function returns nothing), then the internal checking performed by setTimeout() (and setInterval()) will reveal that it hasn't received a function object reference here, and simply abort silently.
相反发生的是 DoMyFunction() 被执行,并且由此产生的任何返回参数然后被传递给 window.setTimeout() 函数。由于 window.setTimeout() 期望在此处传递一个函数对象引用,而是接收您的函数返回的任何内容(如果您的函数不返回任何内容,则接收未定义的内容),那么由 setTimeout()(和 setInterval())执行的内部检查将揭示它在这里没有收到函数对象引用,只是默默地中止。
A far more insidious bug, of course, could arise if DoMyFunction() actually doesreturn a valid function object! If you've written DoMyFunction() to do this, then thatfunction object will be passed to setTimeout() instead, and thatfunction will be run! Of course, you could use this intentionally, and write your DoMyFunction() as a closure, returning the actualfunction you want setTimeout() to execute as a function object return parameter, and if you use thatapproach, then the form:
当然,如果 DoMyFunction()确实返回了一个有效的函数对象,则可能会出现一个更隐蔽的错误!如果您已经编写了 DoMyFunction() 来执行此操作,那么该函数对象将被传递给 setTimeout(),并且该函数将被运行!当然,您可以有意使用它,并将您的 DoMyFunction() 编写为一个闭包,返回您希望 setTimeout() 作为函数对象返回参数执行的实际函数,如果您使用该方法,则形式如下:
discard = window.setTimeout(DoMyFunction(), 1000);
丢弃 = window.setTimeout(DoMyFunction(), 1000);
will no longer be erroneous.
将不再出错。
Remember, everyJavaScript function you write in your code, when that code is parsed, is associated with a function objectby the JavaScript engine. To execute the function, use:
请记住,您在代码中编写的每个JavaScript 函数,当解析该代码时,JavaScript 引擎都会将其与一个函数对象相关联。要执行该函数,请使用:
DoMyFunction();
DoMyFunction();
To reference the function objectinstead, use:
要改为引用函数对象,请使用:
DoMyFunction;
DoMyFunction;
Those () can make a hugeamount of difference according to context, as a result of JavaScript taking this approach to differentiating between a function object referenceand a function execution instruction.
这些 () 可以根据上下文产生巨大的差异,这是 JavaScript 采取这种方法来区分函数对象引用和函数执行指令的结果。
回答by user1990231
Check your code line:
检查您的代码行:
setInterval(getMessages(), queryInterval);
The setInterval
function requires you to pass the reference to your callback function.
该setInterval
函数要求您将引用传递给回调函数。
When you pass getMessages(),
You are actually calling the function and passing its returning object to the setInterval
function.
当您传递时,getMessages(),
您实际上是在调用该函数并将其返回对象传递给该setInterval
函数。
So just change your line to:
所以只需将您的行更改为:
setInterval(getMessages, queryInterval);
and it will works fine!
它会正常工作!