简体   繁体   English

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

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

My ex boss had a weird bug where when he used setInterval with a long delay interval : 我的前任老板有一个奇怪的错误,当他使用setInterval时延迟时间间隔很长

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

Node.js crashed. Node.js崩溃了。

func can be even a simple function that simply console.log('something') . func甚至可以是一个简单的函数,只需console.log('something')

Someone suggested him to wrap an anonymous function around func , and it actually solved his issue. 有人建议他围绕func包装一个匿名函数,它实际上解决了他的问题。

As much as I know, it shouldn't make a difference and even considered to be a bad practice at least in browsers' javascript. 据我所知,至少在浏览器的javascript中它应该没有什么区别甚至被认为是一种不好的做法。

Is there a difference in Node.js between Node.js之间是否存在差异?

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

or is it a bug in Node.js? 或者它是Node.js中的错误?


UPDATE: 更新:

Bug report on GitHub 关于GitHub的错误报告

To address your question directly: Yes, there is a difference. 直接解决您的问题:是的,存在差异。 Not in the functionality of setInterval , but in the scope the function will have when it's run. 不是在setInterval的功能中,而是在函数运行时的范围内。

Scenario 1: 场景1:

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

Every 50 minutes, a stack trace will be printed to console. 每隔50分钟,堆栈跟踪将打印到控制台。 In this case because the function console.trace has been called directly it will maintain the context of console . 在这种情况下,因为函数console.trace已被直接调用,它将维护console的上下文。

Scenario 2: 场景2:

setInterval(console.trace, 3000000);

This will throw an error because it will be invoked with the context of the scope that executes it, not console . 这将抛出一个错误,因为它将使用执行它的作用域的上下文调用,而不是console To maintain context, you can pass a bound copy of the function: 要维护上下文,可以传递函数的绑定副本:

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

It doesn't seem the problem your boss had can be reproduced today. 这似乎不是你的老板今天可以复制的问题。 So, as others have suggested, it may be a problem with garbage collection. 因此,正如其他人所建议的那样,垃圾收集可能存在问题。 However, I would be more inclined to believe that the function your boss was calling depended on a specific context that was maintained via anonymous function but lost when passing an unbound function. 但是,我更倾向于相信你的老板正在调用的函数取决于通过匿名函数维护的特定上下文,但在传递未绑定函数时会丢失。

It's possible that V8 is doing garbage collection behind-the-scenes by removing whatever function you're referencing here as "func". V8可能通过删除你在这里引用的任何函数作为“func”来进行幕后垃圾收集。 This would leave "func" pointing to an invalid function. 这将使“func”指向无效的函数。

Try running node with the following argument: 尝试使用以下参数运行节点:

node --expose-gc app.js

...and then in your code after the setInterval(func, 10000) call: ...然后在setInterval(func,10000)调用后的代码中:

global.gc();

...which will trigger the garbage collection in V8. ...将触发V8中的垃圾收集。 Since I've dropped the timer down to ten seconds you can test the theory without waiting an entire hour. 由于我已将计时器降至十秒,您可以在不等一整个小时的情况下测试理论。

It's entirely possible that wrapping an anonymous function call then prevents garbage collection from removing your actual function from memory. 包装匿名函数调用完全有可能阻止垃圾收集从内存中删除实际函数。

Note that you can also start with: 请注意,您也可以从以下开始:

 node --trace-gc app.js

...which will log garbage collection by V8. ...将通过V8记录垃圾收集。 It might tell you something interesting. 它可能告诉你一些有趣的东西。 See https://groups.google.com/forum/#!topic/nodejs/gITsLR7Zkew 请参阅https://groups.google.com/forum/#!topic/nodejs/gITsLR7Zkew

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

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