我试图了解回调函数在setTimeout函数中的工作原理。我知道格式是:setTimeout(callback, delay)
我写了一个小测试脚本来探索这个。
test1.js
console.log("Hello")
setTimeout(function () { console.log("Goodbye!") }, 5000)
console.log("Non-blocking")
这可以按预期工作,打印Hello <CRLF> Non-blocking
然后5秒后打印Goodbye!
然后我想把这个函数带到setTimeout之外,如下所示:
console.log("Hello")
setTimeout(goodbye(), 5000)
console.log("Non-blocking")
function goodbye () {
console.log("Goodbye")
}
但它不起作用且Non-blocking
和Goodbye!
之间没有5秒的延迟,它们会相互打印。
如果我在超时中删除函数调用中的括号,它会起作用,如下所示:
setTimeout(goodbye, 5000)
但这对我没有意义,因为这不是你怎么称呼一个功能。此外,如果看起来像这样,你将如何将参数传递给函数?!
var name = "Adam"
console.log("Hello")
setTimeout(goodbye(name), 5000)
console.log("Non-blocking")
function goodbye (name) {
console.log("Goodbye "+name)
}
我的问题是,为什么当函数中有参数时它不起作用,尽管事实上setTimeout提供了一个具有正确语法的有效函数?
答案 0 :(得分:4)
通过将括号放在函数名后面,您实际上是在调用它,而不是将函数作为回调函数传递。
为您正在调用的函数提供参数:
setTimeout(function(){goodbye(name)}, 5000);
setTimeout(goodbye, 5000, name);
看看这个问题:How can I pass a parameter to a setTimeout() callback?
答案 1 :(得分:3)
无论您将它放在何处,goodbye(name)
都会立即执行功能。因此,您应该将函数本身传递给setTimeout()
:setTimeout(goodbye, 5000, name)
。
答案 2 :(得分:3)
当你像这样使用它时:
setTimeout(goodbye(), 5000);
首先会调用goodbye
来获取其返回值,然后使用返回的值调用setTimeout
。
您应该使用对回调函数的引用来调用setTimeout
,即仅指定函数的名称,以便获取其引用而不是调用它:
setTimeout(goodbye, 5000);
要在回调函数中发送参数时创建函数引用,可以将其包装在函数表达式中:
setTimeout(function() { goodbye(name); }, 5000);
你可以在调用中使用parantheses,但是函数应该返回对实际回调函数的函数引用:
setTimeout(createCallback(), 5000);
function createCallback() {
return function() {
console.log("Goodbye");
};
}