setInterval() 只运行一次函数

IT技术 javascript setinterval
2021-02-22 06:28:06

我想定期查询新消息的 PHP 脚本。为此,我使用了 setInterval() 函数和 AJAX。

$(document).ready(function(){

    var queryInterval = 1000; /* How fast we query for new messages */

    setInterval(getMessages(), queryInterval);

    function getMessages() {
        console.log("tick");
    }

});

但是,当我查看 Javascript 控制台时,我只看到“滴答”一次。我已经确保控制台不会再忽略相同字符串的更多日志,所以如果代码运行正常,它应该每秒在控制台中显示“滴答”。

有谁知道这里可能出了什么问题?

6个回答

改变:

setInterval(getMessages(), queryInterval);

到:

setInterval(getMessages, queryInterval);
@qwertymk 但我想将参数传递给该函数我该怎么做 this.intervall = setInterval(window.External(this),intervally); 请帮忙
2021-04-21 06:28:06
@qwertymk 在这里完成的是一个链接stackoverflow.com/questions/18819677/...
2021-05-01 06:28:06
@JamilHneini 这样做: setInterval(function() { getMessages(arg) } , queryInterval);
2021-05-10 06:28:06
@qwertymk 我正在使用一个函数,它是一个对象构造函数我有一个函数,它接受 this 对象并做一些我需要在间隔内运行该函数的事情,就像我使用了 function(){ getMessages(this) ,1900); 这被视为窗口而不是对象构造函数
2021-05-14 06:28:06
@JamilHneini 尝试打开一个新问题
2021-05-21 06:28:06

实际上,setInterval根本没有运行getMessages(甚至一次)。setInterval期望对函数引用,但您正在立即执行该getMessages函数并将其返回值传递给(即)。这就是后面的括号所做的。setIntervalundefinedgetMessage

setInterval像这样传递一个引用

setInterval(getMessages, queryInterval);

如果这是唯一使用的地方getMessages,那么你也可以这样写:

setInterval(function() {
    console.log("tick");
}, queryInterval);
@qwertymk 肯定是对的,但为此 +1,因为它更清楚地解释了 setInterval 在幕后的工作原理。
2021-05-03 06:28:06
@jsh - 是的,我不喜欢像被接受的答案那样,虽然正确,但它并没有教太多。了解引用函数与执行函数之间的区别是该语言的一个非常非常基本的基本部分。
2021-05-19 06:28:06

删除()getMessage

这会调用 getMessages,而不是安排它。去掉括号。

setInterval(getMessages(), queryInterval);

setInterval(getMessages, queryInterval);

尽管其他人已经在上面介绍了这一点,但 window.setTimeout() 和 window.setInterval() 都需要函数引用相反,您的代码提供函数调用返回值

当您希望调用或调用 JavaScript 函数时,您可以按预期编写:

DoMyfunction();

JavaScript 引擎将在遇到该行时执行该函数。

但是, setTimeout() 和 setInterval() 需要的是与您的函数相对应的函数对象引用您通过以下方式获得,以及类似的方式:

myFunc = DoMyFunction;

该行将对与 DoMyFunction() 对应函数对象的引用复制到一个新变量中。然后您可以将其传递给 setInterval() 和 setTimeout(),即:

丢弃 = window.setTimeout(myFunc, 1000);

上面那一行将指示 JavaScript 引擎在 1 秒后执行您想要的函数(即 DoMyFunction())一次,并且:

丢弃 = window.setInterval(myFunc, 1000);

将指示 JavaScript 引擎重复执行您的预期功能,每秒一次。

当然,您可以在不使用新变量的情况下实现相同的效果,如下所示:

丢弃 = window.setTimeout(DoMyFunction, 1000);

等等。

但是,如果您错误地使用了:

丢弃 = window.setTimeout(DoMyFunction(), 1000);

相反发生的是 DoMyFunction() 被执行,并且由此产生的任何返回参数然后被传递给 window.setTimeout() 函数。由于 window.setTimeout() 期望在此处传递一个函数对象引用,而是接收您的函数返回的任何内容(如果您的函数不返回任何内容,则接收未定义的内容),那么由 setTimeout()(和 setInterval())执行的内部检查将揭示它在这里没有收到函数对象引用,只是默默地中止。

当然,如果 DoMyFunction()确实返回了一个有效的函数对象,则可能会出现一个更隐蔽的错误如果您已经编写了 DoMyFunction() 来执行此操作,那么函数对象将被传递给 setTimeout(),并且函数将被运行!当然,您可以有意使用它,并将您的 DoMyFunction() 编写为一个闭包,返回您希望 setTimeout() 作为函数对象返回参数执行实际函数,如果您使用方法,则形式如下:

丢弃 = window.setTimeout(DoMyFunction(), 1000);

将不再出错。

请记住,您在代码中编写的每个JavaScript 函数,当解析该代码时,JavaScript 引擎都会将其与一个函数对象相关联要执行该函数,请使用:

DoMyFunction();

改为引用函数对象,请使用:

DoMyFunction;

这些 () 可以根据上下文产生巨大的差异,这是 JavaScript 采取这种方法来区分函数对象引用函数执行指令的结果