您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關nodejs超出最大的調用棧錯誤怎么辦,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
我默默的回到電腦前,努力工作的一天又開始了。由于此表數據量有點略大,該有一千多萬條記錄。所以考慮使用 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超出最大的調用棧錯誤怎么辦”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。