Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/436.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 什么';s setInterval(func)和setInterval(function(){func()})之间的差异_Javascript_Node.js_Windows_V8 - Fatal编程技术网

Javascript 什么';s setInterval(func)和setInterval(function(){func()})之间的差异

Javascript 什么';s setInterval(func)和setInterval(function(){func()})之间的差异,javascript,node.js,windows,v8,Javascript,Node.js,Windows,V8,我的前老板有一个: Node.js崩溃。 func甚至可以是一个简单的函数,只需console.log('something') 有人建议他在func周围包装一个匿名函数,这实际上解决了他的问题 据我所知,它不应该有什么不同,甚至被认为是一个坏习惯,至少在浏览器的javascript中是这样 Node.js中的 setInterval(函数,延迟) setInterval(function(){func()},delay) 或者它是Node.js中的一个bug 更新: V8可能是通过删除您

我的前老板有一个:

Node.js崩溃。

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

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

据我所知,它不应该有什么不同,甚至被认为是一个坏习惯,至少在浏览器的javascript中是这样

Node.js中的

  • setInterval(函数,延迟)
  • setInterval(function(){func()},delay)
或者它是Node.js中的一个bug


更新:


V8可能是通过删除您在此处引用为“func”的任何函数来进行后台垃圾收集。这将使“func”指向无效函数

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

node --expose-gc app.js
…然后在setInterval(func,10000)调用后的代码中:

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

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

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

 node --trace-gc app.js

…它将通过V8记录垃圾收集。它可能会告诉你一些有趣的事情。请参见

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

情景1:

setInterval(function() {
  console.trace();
}, 3000000);
每50分钟,将向控制台打印一次堆栈跟踪。在这种情况下,由于直接调用了console.trace函数,因此它将维护
控制台的上下文

情景2:

setInterval(console.trace, 3000000);
这将引发一个错误,因为它将在执行它的作用域的上下文中被调用,而不是
控制台
。要维护上下文,可以传递函数的绑定副本:

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

看来你老板的问题今天不会重现。因此,正如其他人所建议的,这可能是垃圾收集的问题。但是,我更倾向于相信,您的上司调用的函数依赖于通过匿名函数维护但在传递未绑定函数时丢失的特定上下文。

我不明白为什么使用匿名函数而不是函数名会被视为不好的做法。。。好奇别人怎么说。我认为这两个例子有相同之处。outcome@mplungjan当然,这在一般情况下是不好的做法,它无缘无故地包装了一个函数,通常表明有人并不真正理解函数是JS中的头等。我想知道
func
是否会被收集到这里,因为
setInterval
中的引用不知何故不算数。。。“问得好!”本贾明鲁恩鲍姆,嗯,我明白了。我从来没有遇到过这种情况,所以我想我没有仔细考虑过。很确定这是Node/io.js中的一个bug。我不明白为什么会发生这种情况。仍然有对
createSasTokenTimer
的引用。调用
setInterval
时,它会创建一个
timer
实例,该实例具有名为
\u onTimeout
的属性。一个名为
wrapper
的内部函数被分配给
\onTimeout
,而
wrapper
本身调用
回调
,该回调传递到
setInterval
,它最终是
createSasTokenTimer
。即使释放了主上下文,仍然有一个引用,因此回调仍然是“活动的”。它也没有解释为什么匿名函数最终没有得到GC'd。我想在这里,如果你用匿名调用包装它,它就会走不同的路径,例如,它在线程池中,而不是在主线程中运行。节点中只有一个线程。但这不是重点,因为它与线程无关。OP想知道,当回调作为函数声明的引用传入时,与作为匿名函数的引用传入时相比,为什么过了一段时间后它最终会被取消定义。从
setInterval
的角度来看,没有什么区别,因为它在两种情况下都获得了对函数的引用。每个人都有知识:“NoDE.js有1个永久事件循环:这是V8事件循环。为了处理C++异步任务,它使用线程池[通过LyBeo和LyBeV ]。”我在谈论事件循环;与工人无关。也就是说,如何传入回调(无论是对已声明函数的引用还是函数表达式的引用)与回调在主线程中执行或通过线程池执行无关。
setInterval(console.trace, 3000000);
setInterval(console.trace.bind(console), 3000000);