繁体   English   中英

setInterval(func)和setInterval(function(){func()}之间的区别是什么

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

我的前任老板有一个奇怪的错误,当他使用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中的错误?


更新:

关于GitHub的错误报告

直接解决您的问题:是的,存在差异。 不是在setInterval的功能中,而是在函数运行时的范围内。

场景1:

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

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

场景2:

setInterval(console.trace, 3000000);

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

setInterval(console.trace.bind(console), 3000000);

这似乎不是你的老板今天可以复制的问题。 因此,正如其他人所建议的那样,垃圾收集可能存在问题。 但是,我更倾向于相信你的老板正在调用的函数取决于通过匿名函数维护的特定上下文,但在传递未绑定函数时会丢失。

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

尝试使用以下参数运行节点:

node --expose-gc app.js

...然后在setInterval(func,10000)调用后的代码中:

global.gc();

...将触发V8中的垃圾收集。 由于我已将计时器降至十秒,您可以在不等一整个小时的情况下测试理论。

包装匿名函数调用完全有可能阻止垃圾收集从内存中删除实际函数。

请注意,您也可以从以下开始:

 node --trace-gc app.js

...将通过V8记录垃圾收集。 它可能告诉你一些有趣的东西。 请参阅https://groups.google.com/forum/#!topic/nodejs/gITsLR7Zkew

暂无
暂无

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

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