简体   繁体   English

传递给setInterval的功能范围

[英]Scope of function passed to setInterval

I'm having trouble understanding function scope when called in setInterval. 在setInterval中调用时,我在理解函数作用域时遇到了麻烦。

When I declare an anonymous function directly inside the setInterval like this: 当我直接在setInterval内部声明一个匿名函数时,如下所示:

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

Everything work as expected, I get 一切正常,我得到了

lastEventUUID -> some ID
lastEventUUID -> another ID
...

But when I declare my function separatly 但是当我分别声明我的功能时

 async function myFunc(lastEventUUID) { console.log("lastEventUUID -> " + lastEventUUID); lastEventUUID = "another ID"; } 

And call set it in the setInterval : 并在setInterval调用set:

let lastEventUUID = "some ID";
const interval = setInterval(myFunc, 1000, lastEventUUID);

The lastEventUUID is not updated in the next call, I get 我在下一次通话中未更新lastEventUUID

lastEventUUID -> some ID
lastEventUUID -> some ID
...

What am I missing here ? 我在这里想念什么?

It's nothing to do with defining the function separately or not. 与是否单独定义函数无关。 In your first example, you're using the lastEventID variable that the function closes over. 在第一个示例中,您使用的是函数关闭的lastEventID变量。 In your second example, you're using the lastEventID parameter that is passed to the function. 在第二个示例中,您正在使用传递给该函数的lastEventID 参数 Since setInterval passes it the same one every time, you see the same one every time. 由于setInterval每次都传递相同的内容,因此您每次都会看到相同的内容。

If you do like-for-like, you can define it separately: 如果您进行按赞,则可以单独定义它:

 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 --^ 


Side note: You've defined your function as an async function . 旁注:您已将函数定义为async函数 If your real function is using await in the function body, be sure that you have a try / catch around the full body of the function and that you handle any errors; 如果您的实际函数在函数主体中使用await ,请确保对函数的整个主体进行了一次try / catch并处理了所有错误; otherwise, an error will result in an "Unhandled rejection" error (since the timer mechanism isn't going to do anything with the promise your function returns, including handling rejections). 否则,错误将导致“未处理的拒绝”错误(因为计时器机制对函数返回的诺言不做任何事情,包括处理拒绝)。 If your real function doesn't use await , there's no reason for it to be async . 如果您的实函数不使用await ,则没有理由使其async


Re your comment: 发表您的评论:

From what I understand this work because here lastEventUUID is declared in the global scope, but in my case, it is defined in another function... 据我了解这项工作是因为lastEventUUID是在全局范围内声明的,但就我而言,它是在另一个函数中定义的...

No, it doesn't work because it's a global. 不,它不起作用,因为它是全球性的。 It works because it's declared in the scope the function is defined in or a parent scope. 之所以起作用,是因为在函数定义的作用域或父作用域中声明了它。 It works just fine if that's the scope of a function. 如果那是一个函数的范围,它就可以正常工作。 Example: 例:

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

Globals are just an extreme case of this concept, which is called a closure . 全局变量只是该概念的极端情况,称为闭包 More: How do JavaScript closures work? 更多: JavaScript闭包如何工作?

In fact, if we call that function twice, we see that there is a lastEventID variable for each of them (which is entirely private to the stuff defined within foo ): 实际上,如果我们两次调用该函数,就会看到每个函数都有一个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); 

you can also achieve the same using Closures like this: 您还可以使用Closures达到以下目的:

function myFunc(uuid) {
   return function(){
       console.log("lastEventUUID -> " + uuid);
       uuid = "another ID";
     }
}
let lastEventUUID = "some ID";
const interval = setInterval(myFunc(lastEventUUID), 1000);

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

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