Node.js 中的 setTimeout 细微差别
setTimeout nuances in Node.js
我正在尝试了解回调函数在 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 提供了具有正确语法的有效函数?
无论你把它放在哪里,goodbye(name)
都会立即执行函数。因此,您应该将 函数本身 传递给 setTimeout()
:setTimeout(goodbye, 5000, name)
.
当你这样使用它时:
setTimeout(goodbye(), 5000);
它将首先调用 goodbye
以获取其 return 值,然后它将使用 returned 值调用 setTimeout
。
您应该使用对回调函数的引用来调用 setTimeout
,即仅指定函数的名称以便您获取它的引用而不是调用它:
setTimeout(goodbye, 5000);
当你想向回调函数发送参数时做一个函数引用,你可以将它包装在一个函数表达式中:
setTimeout(function() { goodbye(name); }, 5000);
您 可以 在调用中使用括号,但是函数应该 return 对实际回调函数的函数引用:
setTimeout(createCallback(), 5000);
function createCallback() {
return function() {
console.log("Goodbye");
};
}
通过将括号放在函数名称之后,您实际上是在调用它,而不是将函数作为回调传递。
为您调用的函数提供参数:
- 您可以传递匿名函数。
setTimeout(function(){goodbye(name)}, 5000);
- 或者,您可以将参数作为第三个参数传递。
setTimeout(goodbye, 5000, name);
看这道题:How can I pass a parameter to a setTimeout() callback?
我正在尝试了解回调函数在 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 提供了具有正确语法的有效函数?
无论你把它放在哪里,goodbye(name)
都会立即执行函数。因此,您应该将 函数本身 传递给 setTimeout()
:setTimeout(goodbye, 5000, name)
.
当你这样使用它时:
setTimeout(goodbye(), 5000);
它将首先调用 goodbye
以获取其 return 值,然后它将使用 returned 值调用 setTimeout
。
您应该使用对回调函数的引用来调用 setTimeout
,即仅指定函数的名称以便您获取它的引用而不是调用它:
setTimeout(goodbye, 5000);
当你想向回调函数发送参数时做一个函数引用,你可以将它包装在一个函数表达式中:
setTimeout(function() { goodbye(name); }, 5000);
您 可以 在调用中使用括号,但是函数应该 return 对实际回调函数的函数引用:
setTimeout(createCallback(), 5000);
function createCallback() {
return function() {
console.log("Goodbye");
};
}
通过将括号放在函数名称之后,您实际上是在调用它,而不是将函数作为回调传递。
为您调用的函数提供参数:
- 您可以传递匿名函数。
setTimeout(function(){goodbye(name)}, 5000);
- 或者,您可以将参数作为第三个参数传递。
setTimeout(goodbye, 5000, name);
看这道题:How can I pass a parameter to a setTimeout() callback?