首頁  >  文章  >  web前端  >  nodejs超出最大的呼叫堆疊錯誤問題解決方法

nodejs超出最大的呼叫堆疊錯誤問題解決方法

小云云
小云云原創
2017-12-27 13:56:451654瀏覽

本文主要介紹了nodejs超出最大的呼叫堆疊錯誤問題,需要的朋友可以參考下,希望能幫助到大家。

程式實現的程式碼大致如下


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);

相關推薦:

##JavaScript呼叫堆疊、尾遞歸和手動最佳化的詳細介紹

前端進階(六):觀察函數呼叫堆疊、作用域鏈與閉包

#前端基礎進階(六):在chrome開發者工具中觀察函數呼叫棧、作用域鏈與閉包

以上是nodejs超出最大的呼叫堆疊錯誤問題解決方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn