2015-07-21 51 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