2015-07-21 48 views
4

我的应用程序,其中的操作需要很长的时间才能完成的情况,然后几百情况下,下面的消息被打印:Node.js - 诊断“(节点)警告:检测到递归process.nextTick。”

(node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral. 

然后应用程序崩溃,:

RangeError: Maximum call stack size exceeded 

没有堆栈跟踪。

如何诊断此类错误?我想知道,例如,在RangeError之前的哪个函数调用。

复制错误,该文件foo.js具有以下内容运行node foo.js

var foo = function() { 
    process.nextTick(foo); 
}; 
foo(); 

我不是那么这个问题的具体原因有兴趣在我的应用程序,因为我知道如何来在节点中诊断这类问题。

节点版本是v0.10.39

+0

'节点--trace foo.js> trace.log'可能会得到你的地方,但我怀疑它的可用于真实应用程序的上下文中,因为它可能会引入太多副作用。 – robertklep

回答

0

可以更换process.nextTick打印某种有用的信息 - 沿着线的东西:

var _nextTick = process.nextTick; 
var alreadyLogged = new Set(); 

process.nextTick = function nextTick(f) { 
    if (!alreadyLogged.has(f)) { 
     alreadyLogged.add(f); 

     process.nextTick = _nextTick; 
     console.log(f); 
     process.nextTick = nextTick; 
    } 

    return _nextTick.apply(this, arguments); 
}; 
+1

我不知道这是如何解决这个问题的。这会阻止递归,但不会记录导致它的原因?而且,当检测到递归调用时它不记录。而且,第二次调用'process.nextTick()'时,会传递相同的函数,所以也会被阻塞,因为'Set'永远不会被清除。这似乎是一个有趣的方向,但不到一半实施。 – jfriend00

+0

@ jfriend00:对不起,这只是一个错误。它并不是要阻止递归;只记录任何一次最多传递的函数。 – Ryan

+0

我试过了,但在我的应用程序中,启动时出现“RangeError:Maximum call stack size exceeded”。一些其他函数function(){afterWrite(stream,state,finished,cb); }当我切换到记录'f'的'toString'值时记录了很多次。 – Jackson