简体   繁体   English

在JavaScript中使用setTimeout()和setInterval()时调用函数

[英]Calling a function when using setTimeout() and setInterval() in JavaScript

If I call a named function using setTimeout() and setInterval() without the parentheses it works as expected. 如果我使用不带括号的setTimeout()和setInterval()调用命名函数,它将按预期工作。 When I call the same function with the parentheses it either executes it immediately or gives an error. 当我用括号调用相同的函数时,它要么立即执行它,要么给出错误。

I am looking for a deeper understanding in this matter then what I have found on the web. 我正在寻找比我在网上发现的更深刻的理解。 Would you guys please explain to me why this is true? 你们能告诉我为什么这是真的吗?

var func = function(){
    console.log("Bowties are cool.");
}

setTimeout(func(), 1500);
// Prints "Bowties are cool." immediately

setInterval(func(), 1500);
// Throws an error

setInterval(func, 1500);
// Works as expected

setTimeout(console.log("Bowties are cool."),1500);
// This method has the same result as "setTimeout(func(), 1500)".

You must pass a function reference to both setTimeout() and setInterval() . 您必须将函数引用传递给setTimeout()setInterval() That means you pass a function name without the () after it or you pass an anonymous function. 这意味着您传递的函数名称后不带() ,或者传递匿名函数。

When you include the () after the function name as in func() , you are executing the function immediately and then passing the return result to setInterval() or to setTimeout() . 当包括()函数名后,如func()你会立即执行该功能,然后通过返回结果setInterval()setTimeout() Unless the function itself returns another function reference, this will never do what you want. 除非函数本身返回另一个函数引用,否则它将永远不会做您想要的事情。 This is a very common mistake for Javascript programmers (I made the same mistake myself when learning the language). 对于Javascript程序员来说,这是一个非常常见的错误(我自己在学习语言时犯了同样的错误)。

So, the correct code is: 因此,正确的代码是:

setTimeout(func, 1500);
setInterval(func, 1500);

If you know other languages that use pointers, you can think of the name of a function with the () after it as like a pointer to the function and that's what a function reference is in Javascript and that's what you pass to a function when you want it to be able to execute some function later, not immediately. 如果您知道其他使用指针的语言,则可以在函数名称后加上()来表示该函数的名称,就像该函数的指针一样,这就是Javascript中的函数引用,也就是您在传递给函数时的含义希望它能够稍后而不是立即执行某些功能。


When you mistakenly do this: 当您错误地执行此操作时:

setTimeout(func(), 1500);
setInterval(func(), 1500);

It is executing your func() immediately and then passing the return result to setTimeout() and setInterval() . 它会立即执行func() ,然后将返回结果传递给setTimeout()setInterval() Since your func() doesn't return anything, you are essentially doing this: 由于func()不返回任何内容,因此您实际上是在这样做:

func();
setTimeout(undefined, 1500);

Which is what you observe happening, but not what you want. 您观察到的是正在发生的事情,而不是您想要的。


Further, if you want to execute a specific function call such as console.log("Bowties are cool.") , then you can wrap it in another function like this: 此外,如果要执行特定的函数调用,例如console.log("Bowties are cool.") ,则可以将其包装在另一个函数中,如下所示:

setTimeout(function() {
    console.log("Bowties are cool.")
}, 1500);

So, again you are passing a function reference to setTimeout() that can be executed LATER rather than executing it immediately which is what you were doing. 因此,您再次向setTimeout()传递了一个函数引用,该函数引用可以稍后执行,而不是立即执行此操作。

setTimeout and setInterval expect a function reference to be passed to them. setTimeout和setInterval希望将函数引用传递给它们。 You should not be calling the function within the setTimeout and setInterval calls. 您不应在setTimeout和setInterval调用内调用该函数。

Incorrect ( DON'T DO THIS ): 不正确( 请勿这样做 ):

setTimeout(func(), 1500);
setInterval(func(), 1500);
setTimeout(console.log("Bowties are cool."), 1500);
setInterval(console.log("Bowties are cool."), 1500);

Correct: 正确:

setTimeout(func, 1500);
setInterval(func, 1500);
setTimeout(function() {
    console.log("Bowties are cool.");
}, 1500);
setInterval(function() {
    console.log("Bowties are cool.");
}, 1500);

Note how I wrapped the console.log in an anonymous function in order to use it with setInterval and setTimeout. 请注意我如何将console.log包裹在一个匿名函数中,以便与setInterval和setTimeout一起使用。 I could not pass console.log to the setInterval and setTimeout functions, because it needs the parameter "Bowties are cool." 我无法将console.log传递给setInterval和setTimeout函数,因为它需要参数"Bowties are cool." . Wrapping it in the anonymous function solves this. 将其包装在匿名函数中可以解决此问题。

When you add parentheses after a defined function, you actually call or invoke the function. 在定义的函数后添加括号时,实际上是在调用或调用该函数。

But when you pass a function as a parameter inside another function, you don't want to call the function, you just want to pass a reference to this function as a parameter, (and the function you passed in, will be available to be called when needed). 但是,当您将一个函数作为参数传递给另一个函数时,您不想调用该函数,而只是想将该函数的引用作为参数传递,(而您传入的函数将可用于在需要时调用)。

for more about callback functions in general, here . 有关一般回调函数的更多信息,请参见此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM