当使用较长的setInterval间隔时,Node.js会崩溃

30
function createSasTokenTimer() {    
    console.log("Hello");
}

setInterval(createSasTokenTimer, 3000000);

我运行了这段代码,50分钟后出现了以下错误:

Hello
timers.js:265
    callback.apply(this, args);
            ^
TypeError: Cannot read property 'apply' of undefined

    at wrapper [as _onTimeout] (timers.js:265:13)
    at Timer.listOnTimeout (timers.js:110:15)

当间隔时间较短时(例如2000000),一切正常。

这是Node.js的一个bug吗?


更新:

操作系统:Windows,Node.js版本:0.12.4

当我只运行上面的代码时,它可以正常工作,但当它在我的应用程序中时,它会出错。我无法确定哪个部分的代码导致了错误,因为我的代码非常冗长,并且没有看起来“可疑”的地方。不管怎样,当间隔时间较短时,它能够正常工作。


2
@janiv 这是唯一运行的代码吗? - Tasos Vogiatzoglou
Timeout_Max 被设置为 2^32-1,所以这绝对不是问题。 - Rahat Mahbub
1
@janiv 我已经测试了这段代码,它似乎可以正常工作。这是唯一在运行的东西吗?比如说,这个函数有可能未定义吗? - Tasos Vogiatzoglou
2
看起来是本地C++绑定和V8垃圾回收器之间交互的一个bug。通过保留setInterval返回的对象,这个问题应该很容易解决。我正在深入研究。 - Ginden
2
Node.js 实现的 setTimeout 和 setInterval 返回一个对象,而浏览器返回一个整数。 - Ginden
显示剩余14条评论
2个回答

1

不要直接调用函数,而是将其放在回调函数中。

function createSasTokenTimer() {    
  console.log("Hello");
}

setInterval(function(){
 createSasTokenTimer();
}, 3000000);

使用这种方法,您将匿名函数传递给setInterval。它将按间隔(在此示例中为3000000毫秒)每次调用该函数一次。
现在,您可以使用此代码。为了进一步了解,请研究匿名函数和闭包。
希望这有所帮助。

你能解释一下为什么这有帮助吗?我已经和Janiv交谈过了,他确认你的答案解决了他的问题。之后我会给你悬赏。 - gdoron
2
我非常熟悉JavaScript中的异步编程,但仍然不明白setInterval(funcName, delay)setInterval(function(){funcName()}, delay)之间有什么区别,至少在浏览器的JavaScript中它们是相同的。 - gdoron
2
即使它能工作,这个答案也是错误的。解释完全无关。 - vkurchatkin
这完全没有回答楼主的问题,而且是错误的。 - Vivin Paliath
1
@SUNDARRAJANK:在JavaScript中,每个函数都是闭包,无论它是否匿名。如果你将函数包装在另一个匿名函数中,行为上不应该有任何区别,因为setTimeout应该保存对函数的引用并防止其被垃圾回收(确实,命名函数永远不应该被垃圾回收,但匿名函数可能会被垃圾回收)。这是Node.js中一个明显的错误。 - slebetman
显示剩余5条评论

0
在我看来,这似乎是您正在使用非标准模块而不是本地模块。请查看global.process.moduleLoadList,它应该有条目。
 'NativeModule timers',
 'Binding timer_wrap',

请检查您的代码,确保没有导入第三方的timers.js文件


我没有导入第三方的timers.js。我应该在哪里查找NativeModule和Binding? - janiv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接