這篇文章主要介紹了nodejs超出最大的呼叫棧錯誤問題,需要的朋友可以參考下
今天早上老大和我說之前項目裡面的那個數據要改動,要對mongodb 中每筆記錄進行update 操作,你寫個腳本跑一下吧。
然後,我默默的回到電腦前,努力工作的一天又開始了。由於此表資料量有點略大,該有一千多萬筆記錄。所以考慮使用 mongodb 的 cursor 遊標來進行遍歷修改。
程式實現的程式碼大致如下
function modify(cursor) { cursor.hasNext(function(err,bool) { if(err) { return console.log(err); } if(bool) { cursor.next(function(err, item){ if(err) { return console.log(err); } /* 此处为对数据进行update操作 */ // 递归调用modify方法 return modify(cursor); }); }else{ console.log('finished'); } }) } var cursor = collection.find(); modify(cursor);
然後讓它慢慢跑吧,可是一個令我鬱悶的事情發生了。當遊標跑到接近500萬的時候,程式崩了,提示Uncaught RangeError: Maximum call stack size exceeded
##竟然告訴我爆棧了,什麼情況?哎,排查代碼,開始填坑。發現我上面遞歸調用了modify() ,而且遞歸次數有點小多(1000多萬條記錄的表啊),可能是函數不斷的遞歸調用導致它的調用棧不斷的增加,然後越來越大,最終就沒有然後了,爆棧了。看來得給個機會讓node進行垃圾回收一下,要想讓它有機會垃圾回收那就只得終結一下遞歸啊。使用系統的setTimeout();來跳出遞歸呼叫棧吧。 程式碼修改如下function modify(cursor) { cursor.hasNext(function(err,bool) { if(err) { return console.log(err); } if(bool) { cursor.next(function(err, item){ if(err) { return console.log(err); } /* 此处对数据进行update操作 */ // 递归调用modify方法 return setTimeout(function(){ //跳出递归调用栈 modify(cursor); },0); }); }else{ console.log('finished'); } }) } var cursor = collection.find(); modify(cursor);在跑一下試試。 。 。 。 ok,好使了。但是運行有點慢啊,因為我每次都讓它跳出遞歸呼叫棧了。這樣雖然沒問題但是沒必要,因為400多萬才會出現爆棧呢。加個計數器吧,等到呼叫棧有點大的時候就跳出來。
var count = 0; function modify(cursor) { count++; cursor.hasNext(function(err,bool) { if(err) { return console.log(err); } if(bool) { cursor.next(function(err, item){ if(err) { return console.log(err); } /* 此处对数据进行update操作 */ // 递归调用modify方法 if(count%10000 === 0) { return setTimeout(function(){ //跳出递归调用栈 modify(cursor); },0); }else{ return modify(cursor); } }); }else{ console.log('finished'); } }) } var cursor = collection.find(); modify(cursor);上面是我整理給大家的,希望今後會對大家有幫助。 相關文章:
以上是在nodejs中如何解決超出最大的呼叫堆疊錯誤的詳細內容。更多資訊請關注PHP中文網其他相關文章!