在setInterval中调用时,我无法理解函数范围。
当我在setInterval中直接声明一个匿名函数时,如下所示:
let lastEventUUID = "some ID";
const interval = setInterval(async function() {
console.log("lastEventUUID -> " + lastEventUUID);
lastEventUUID = "another ID";
}, 1000);

一切都按预期工作,我得到了
lastEventUUID -> some ID
lastEventUUID -> another ID
...
但是当我分开宣布我的功能时
async function myFunc(lastEventUUID) {
console.log("lastEventUUID -> " + lastEventUUID);
lastEventUUID = "another ID";
}

并且在setInterval
:
let lastEventUUID = "some ID";
const interval = setInterval(myFunc, 1000, lastEventUUID);
lastEventUUID
未在下次通话中更新,我
lastEventUUID -> some ID
lastEventUUID -> some ID
...
我在这里缺少什么?
答案 0 :(得分:5)
与单独定义功能无关。在第一个示例中,您将使用函数关闭的lastEventID
变量。在第二个示例中,您使用了传递给函数的lastEventID
参数。由于setInterval
每次都传递相同的一个,所以每次都会看到相同的一个。
如果您喜欢这样,可以单独定义:
async function myFunc() {
// ^----- No parameter declared
console.log("lastEventUUID -> " + lastEventUUID);
lastEventUUID = "another ID";
}
let lastEventUUID = "some ID";
const interval = setInterval(myFunc, 1000);
// No argument given to pass to myFunc --^

旁注:您已将自己的功能定义为async
function。如果你的真实功能是在函数体中使用await
,请确保在函数的完整主体周围有一个try
/ catch
并且你处理任何错误;否则,错误将导致"未处理的拒绝"错误(因为计时器机制不会对你的函数返回的承诺做任何事情,包括处理拒绝)。如果您的真实功能没有使用await
,则没有理由将其async
。
重新评论:
从我理解这项工作,因为这里lastEventUUID在全局范围内声明,但在我的情况下,它在另一个函数中定义...
不,它不起作用,因为它是一个全球性的。它的工作原理是它在函数定义的作用域或父作用域中声明。如果它是函数的范围,它就可以正常工作。例如:
function foo() {
async function myFunc() {
console.log("lastEventUUID -> " + lastEventUUID);
lastEventUUID = "another ID";
}
let lastEventUUID = "some ID";
const interval = setInterval(myFunc, 1000);
}
foo();

Globals只是这个概念的极端情况,称为闭包。更多:How do JavaScript closures work?
事实上,如果我们将该函数调用两次,我们会发现每个都有一个lastEventID
变量(对于{{1}中定义的内容完全是私有的}):
foo

答案 1 :(得分:0)
你也可以使用这样的Closures来实现同样的目标:
function myFunc(uuid) {
return function(){
console.log("lastEventUUID -> " + uuid);
uuid = "another ID";
}
}
let lastEventUUID = "some ID";
const interval = setInterval(myFunc(lastEventUUID), 1000);