nodejs超出最大的調(diào)用棧錯誤問題
今天早上老大和我說之前項目里面的那個數(shù)據(jù)要改動,要對 mongodb 中每條記錄進行 update 操作,你寫個腳本跑一下吧。
然后,我默默的回到電腦前,努力工作的一天又開始了。由于此表數(shù)據(jù)量有點略大,該有一千多萬條記錄。所以考慮使用 mongodb 的 cursor 游標來進行遍歷修改。
程序?qū)崿F(xiàn)的代碼大致如下
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);
}
/* 此處為對數(shù)據(jù)進行update操作 */
// 遞歸調(diào)用modify方法
return modify(cursor);
});
}else{
console.log('finished');
}
})
}
var cursor = collection.find();
modify(cursor);
然后讓它慢慢跑吧,可是一個令我郁悶的事情發(fā)生了。當游標跑到接近500萬的時候,程序崩了,提示Uncaught RangeError: Maximum call stack size exceeded
竟然告訴我爆棧了,什么情況? 哎,排查代碼,開始填坑。發(fā)現(xiàn)我上面遞歸調(diào)用了modify() ,而且遞歸次數(shù)有點小多(1000多萬條記錄的表?。?,可能是函數(shù)不斷的遞歸調(diào)用導致它的調(diào)用棧不斷的增加,然后越來越大,最終就沒有然后了,爆棧了??磥淼媒o個機會讓node進行垃圾回收一下,要想讓它有機會垃圾回收那就只得終結(jié)一下遞歸啊。使用系統(tǒng)的setTimeout();來跳出遞歸調(diào)用棧吧。
代碼修改如下
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);
}
/* 此處對數(shù)據(jù)進行update操作 */
// 遞歸調(diào)用modify方法
return setTimeout(function(){
//跳出遞歸調(diào)用棧
modify(cursor);
},0);
});
}else{
console.log('finished');
}
})
}
var cursor = collection.find();
modify(cursor);
在跑一下試試。。。。ok,好使了。但是運行有點慢啊,因為我每次都讓它跳出遞歸調(diào)用棧了。這樣雖然沒問題但是沒必要,因為400多萬才會出現(xiàn)爆棧呢。加個計數(shù)器吧,等調(diào)用棧有點大的時候在跳出來。
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);
}
/* 此處對數(shù)據(jù)進行update操作 */
// 遞歸調(diào)用modify方法
if(count%10000 === 0) {
return setTimeout(function(){
//跳出遞歸調(diào)用棧
modify(cursor);
},0);
}else{
return modify(cursor);
}
});
}else{
console.log('finished');
}
})
}
var cursor = collection.find();
modify(cursor);
總結(jié)
以上所述是小編給大家介紹的nodejs超出最大的調(diào)用棧錯誤問題,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
詳解如何在vscode里面調(diào)試js和node.js的方法步驟
這篇文章主要介紹了詳解如何在vscode里面調(diào)試js和node.js的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12
Express使用multer實現(xiàn)文件上傳的示例代碼
這篇文章主要介紹了Express 使用 multer 實現(xiàn)文件上傳的操作步驟,文中通過代碼示例和圖文結(jié)合的方式講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2024-03-03

