Heim  >  Artikel  >  Web-Frontend  >  Lösung für das Problem mit dem maximalen Aufrufstapelfehler von nodejs

Lösung für das Problem mit dem maximalen Aufrufstapelfehler von nodejs

小云云
小云云Original
2017-12-27 13:56:451654Durchsuche

Dieser Artikel stellt hauptsächlich das Problem dar, dass Nodejs den maximalen Call-Stack-Fehler überschreiten. Freunde in Not können sich darauf beziehen.

Der vom Programm implementierte Code ist ungefähr wie folgt


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

Dann lass es langsam laufen, aber es ist etwas passiert, das mich deprimiert hat. Als der Cursor fast 5 Millionen erreichte, stürzte das Programm ab und meldete Uncaught RangeError: Maximum call stack size failed

und teilte mir tatsächlich mit, dass der Stack explodiert sei. Was ist passiert? Hey, überprüfe den Code und fang an, die Lücken zu füllen. Ich habe festgestellt, dass ich oben „modify()“ rekursiv aufgerufen habe und die Anzahl der Rekursionen etwas gering war (eine Tabelle mit mehr als 10 Millionen Datensätzen). Es kann sein, dass die ständigen rekursiven Aufrufe der Funktion dazu führten, dass der Aufrufstapel weiter zunahm Dann wird es immer größer und schließlich ist nichts mehr da, der Stapel explodiert. Es scheint, dass wir dem Knoten die Möglichkeit geben müssen, die Speicherbereinigung durchzuführen. Wenn wir möchten, dass er die Möglichkeit hat, die Speicherbereinigung durchzuführen, müssen wir die Rekursion beenden. Verwenden Sie setTimeout(); des Systems, um aus dem rekursiven Aufrufstapel zu springen.

Der Code wird wie folgt geändert


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

Versuchen Sie, ihn auszuführen. . . . ok, es funktioniert. Aber es läuft etwas langsam, weil ich es jedes Mal aus dem rekursiven Aufrufstapel herausspringen lassen muss. Das ist zwar in Ordnung, aber nicht notwendig, da der Stapel erst nach mehr als 4 Millionen explodiert. Fügen Sie einen Zähler hinzu und klappen Sie ihn heraus, wenn der Aufrufstapel etwas größer wird.


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

Verwandte Empfehlungen:

Detaillierte Einführung in JavaScript-Aufrufstapel, Tail-Rekursion und manuelle Optimierung

Front-End Advanced (6): Funktionsaufrufstapel, Bereichskette und Abschluss beobachten

Front-End Basic Advanced (6): Funktionen im Aufrufstapel der Chrome-Entwicklertools beobachten , Zielfernrohrkette und Verschluss

Das obige ist der detaillierte Inhalt vonLösung für das Problem mit dem maximalen Aufrufstapelfehler von nodejs. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn