setInterval(func)和setInterval(function(){func()})有什么区别?

What's the difference between setInterval(func) and setInterval(function(){func()})

本文关键字:setInterval func 什么 区别 function      更新时间:2023-09-26

我的前任老板有一个奇怪的bug,当他使用setInterval时,延迟间隔很长:

setInterval(func, 3000000 /*50 minutes*/);

node . js崩溃了。

func甚至可以是一个简单的函数,即简单的console.log('something')

有人建议他在func周围包装一个匿名函数,这实际上解决了他的问题。

据我所知,它不应该有什么不同,甚至被认为是一个坏的做法,至少在浏览器的javascript。

在Node.js中

  • setInterval(func, delay)
  • setInterval(function(){func()}, delay)

还是Node.js中的一个bug ?


更新:

GitHub上的Bug报告

直接回答你的问题:是的,有区别。不是在setInterval的功能中,而是在函数运行时的作用域中。

场景1:

setInterval(function() {
  console.trace();
}, 3000000);

每隔50分钟,堆栈跟踪将被打印到控制台。在这种情况下,因为功能控制台。如果直接调用trace,它将维护console的上下文。

场景2:

setInterval(console.trace, 3000000);

这将抛出一个错误,因为它将在执行它的作用域的上下文中调用,而不是console。为了维护上下文,可以传递函数的绑定副本:

setInterval(console.trace.bind(console), 3000000);
看来你老板遇到的问题今天不会再出现了。因此,正如其他人所建议的,这可能是垃圾收集的问题。然而,我更倾向于相信你的老板调用的函数依赖于一个特定的上下文,这个上下文是通过匿名函数维护的,但是在传递一个未绑定的函数时丢失了。

有可能V8在后台通过删除你在这里引用的任何函数作为"func"来进行垃圾收集。这将使"func"指向一个无效的函数。

尝试使用以下参数运行node:

node --expose-gc app.js

…然后在你的代码setInterval(func, 10000)调用之后:

global.gc();

…这将在V8中触发垃圾收集。既然我把计时器降到了10秒,你就可以测试这个理论了,而不用等整整一个小时。

完全有可能包装一个匿名函数调用,然后防止垃圾收集从内存中删除您的实际函数。

注意你也可以以:

开头
 node --trace-gc app.js

…它将记录V8的垃圾收集。它可能会告诉你一些有趣的事情。见https://groups.google.com/forum/# !主题/nodejs gITsLR7Zkew