Dieser Artikel stellt hauptsächlich das Problem vor, dass Nodejs den maximalen Aufrufstapelfehler überschreiten. Freunde, die ihn benötigen, können sich darauf beziehen
Heute Morgen sagte mir der Chef, dass die Daten im vorherigen Projekt geändert werden müssen , und jede Datei in mongodb muss aktualisiert werden. Um Datensätze zu aktualisieren, können Sie ein Skript schreiben und ausführen.
Dann kehrte ich schweigend zum Computer zurück und der Tag harter Arbeit begann von neuem. Da das Datenvolumen dieser Tabelle etwas groß ist, sollten es mehr als 10 Millionen Datensätze sein. Erwägen Sie daher die Verwendung des Mongodb-Cursors zum Durchlaufen und Ändern.
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 Garbage Collection durchzuführen. Wenn wir möchten, dass er die Garbage Collection durchführen kann, 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);
Ich habe das Obige für Sie zusammengestellt und hoffe, dass es Ihnen in Zukunft hilfreich sein wird.
Verwandte Artikel:
So verwenden Sie die Generator-Methode in JavaScript
So ändern Sie den Avatar im Knoten
Beim Aktualisieren der Seite im React-Router tritt ein 404-Problem auf
Detaillierte Einführung in die Verwendung der Vue-Ereignismodifikatorerfassung
Das obige ist der detaillierte Inhalt vonSo beheben Sie den Fehler „Maximaler Aufrufstapel überschritten' in NodeJS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!