この記事では、nodejs が最大コールスタックエラーを超える問題を主に紹介します。必要な友人は参照してください
今朝、上司から、前のプロジェクトのデータと mongodb のすべてのレコードを変更する必要があると言われました。スクリプトを作成して実行するだけです。
そして、黙ってパソコンに戻り、またハードワークの一日が始まりました。このテーブルのデータ量は少し大きいので、レコード数は 1,000 万を超えるはずです。したがって、mongodb のカーソルを使用してトラバースして変更することを検討してください。
プログラムで実装されているコードはおおよそ以下の通りです
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 sizeowned
というメッセージが表示され、スタックが爆発したことが実際に表示されました。 コードをチェックして、穴を埋め始めてください。上記で、modify() を再帰的に呼び出したことがわかりましたが、再帰の数は少し少なかったです (1,000 万件を超えるレコードを持つテーブルの場合)。おそらく、関数の定期的な再帰呼び出しにより、呼び出しスタックが増加し続けた可能性があります。そしてどんどん大きくなり、最後にはもう限界があり、スタックが爆発します。ノードにガベージ コレクションを実行する機会を与える必要があるようです。ガベージ コレクションを実行する機会を与えたい場合は、再帰を終了する必要があります。システムの 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);
実行してみてください。 。 。 。わかりました、うまくいきます。ただし、毎回再帰呼び出しスタックからジャンプする必要があるため、実行が少し遅くなります。これは問題ありませんが、スタックが 400 万を超えると爆発するだけなので、必須ではありません。カウンターを追加し、呼び出しスタックが少し大きくなったらポップアウトします。
rreee以上が皆さんのためにまとめたもので、今後皆さんのお役に立てれば幸いです。
関連記事:
react-routerでページを更新すると404問題が発生する
以上がNodejsでの最大コールスタック超過エラーを解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。