传递给setInterval的函数范围

Thé*_*ion 1 javascript setinterval

在setInterval中调用时,我无法理解函数范围.

当我在setInterval中直接声明一个匿名函数时,如下所示:

let lastEventUUID = "some ID";
const interval = setInterval(async function() {
  console.log("lastEventUUID -> " + lastEventUUID);
  lastEventUUID = "another ID";
}, 1000);
Run Code Online (Sandbox Code Playgroud)

我得到的一切都按预期工作

lastEventUUID -> some ID
lastEventUUID -> another ID
...
Run Code Online (Sandbox Code Playgroud)

但是当我分开宣布我的功能时

async function myFunc(lastEventUUID) {
  console.log("lastEventUUID -> " + lastEventUUID);
  lastEventUUID = "another ID";
}
Run Code Online (Sandbox Code Playgroud)

并将调用设置为setInterval:

let lastEventUUID = "some ID";
const interval = setInterval(myFunc, 1000, lastEventUUID);
Run Code Online (Sandbox Code Playgroud)

lastEventUUID没有在下次通话中更新

lastEventUUID -> some ID
lastEventUUID -> some ID
...
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么?

T.J*_*der 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 --^
Run Code Online (Sandbox Code Playgroud)


附注:您已将功能定义为async功能.如果您的实际功能await在函数体中使用,请确保您在函数的整个主体周围有try/ 并且您处理任何错误; 否则,错误将导致"未处理拒绝"错误(因为计时器机制不会对您的函数返回的承诺执行任何操作,包括处理拒绝).如果您的真实功能不使用,则没有理由这样做.catchawaitasync


你的评论:

从我理解这项工作,因为这里lastEventUUID在全局范围内声明,但在我的情况下,它在另一个函数中定义...

不,它不起作用,因为它是一个全球性的.它的工作原理是它在函数定义的作用域或父作用域中声明.如果这是函数的范围,它的工作正常.例:

function foo() {
  async function myFunc() {
    console.log("lastEventUUID -> " + lastEventUUID);
    lastEventUUID = "another ID";
  }
  let lastEventUUID = "some ID";
  const interval = setInterval(myFunc, 1000);
}
foo();
Run Code Online (Sandbox Code Playgroud)

Globals只是这个概念的一个极端情况,称为闭包.更多:JavaScript闭包如何工作?

实际上,如果我们将该函数调用两次,我们会看到每个函数都有一个lastEventID变量(它对于在其中定义的内容完全是私有的):foo

function foo(x) {
  async function myFunc() {
    console.log("x -> " + x + ", lastEventUUID -> " + lastEventUUID);
    lastEventUUID = "another ID";
  }
  let lastEventUUID = "some ID";
  const interval = setInterval(myFunc, 1000);
}
foo(1);
foo(2);
Run Code Online (Sandbox Code Playgroud)