1

私はすでに数日かかった問題を抱えており、それを完全に理解することができません。node.jsを使用しており、座標のインデックスが付けられた場所を持つmongodbがあります。事前にインデックスが正常に動作することを確認しました。座標のセットについては、最も近い場所を見つけたいと思います。これが私がそれについて行こうとした方法です:

    var Places = require(./models/places.js),
        coordFinder = require('./coordFinder.js');

    ...

    function getCoords(userId, callback) {
       coordFinder.getCoords(userId, function(err, coords) {
          if (err) {
             callback(err);
          } else {   
             callback(null, coords);
          }
       }
    }

    function getNearestPlaces(coords, callback) {
       async.forEachSeries(
          coords,
          function(coord, done) {
             Places.findOne(
                { coordinates: { $near: [ coord.lat, coord.lon ] } },
                function(err, place) {
                   // do something with place
                   done();
                }
             )
          },
          function(err) {
             callback(err ? err : null);    
          }
       );
    }

    ...

    async.waterfall(
       [
          ...
          getCoords,
          getNearestPlaces,
          ...
       ],
       function(err) {
          ...
       }
    }

mongodbクエリは一貫して失敗し、最初のクエリに対して次のエラーメッセージが表示されます。

RangeError: Maximum call stack size exceeded

クエリをに変更するgetNearestPlaces

... { $near: [ 10, 10 ] } ...

私は一貫してエラーがなく、正しい場所を取得します。coordFinderinへの呼び出しを避けてにgetCoords変更getCoordsした場合も同じことが起こります

function getCoords(userId, callback) {
    callback(
        null, 
        [ 
           // some coordinates
        ]
    );

エラーがスタックオーバーフローを示していることは知っていますが(スタックサイズを増やしても効果がありませんでした)、どのようにしてスタックオーバーフローが発生したのかわかりません。なぜこれが起こるのかについて誰かが手がかりを持っていますか?洞察を事前に感謝します!

編集mongodb-native:ちなみに、直接使用した場合も同じ問題が発生したmongooseので、問題ないようです。もう1つの手がかり-同じクエリを使用しても、コールバック内から呼び出さなくても問題は発生しません。それがエラーの原因でしょうか?

私が使う

  • node.js 0.6.14
  • mongodb 2.2.2
  • ノードモジュール非同期0.1.22
  • ノードモジュールmongodb1.2.5
  • ノードモジュールマングース2.5.7

乾杯、ゲオルク

4

2 に答える 2

2

問題は、の隠れた再帰に起因する可能性が最も高いですasync.forEachSeriesPlaces.findOne次のように通話をラップしてみてくださいsetTimeout

function getNearestPlaces(coords, callback) {
   async.forEachSeries(
      coords,
      function(coord, done) {
         setTimeout(function () {
             Places.findOne(
                 { coordinates: { $near: [ coord.lat, coord.lon ] } },
                 function(err, place) {
                     // do something with place
                     done();
                 }
             );
         }, 1);
      },
      function(err) {
         callback(err ? err : null);    
      }
   );
}

これにより、Places.findOne呼び出しはの呼び出しスタックの外に置かれますasync.forEachSeries

于 2012-12-21T03:50:49.327 に答える
1

mjhmは私を正しい方向に向けました。どうやら、マングースクエリに渡されたインスタンス化された番号がスタックオーバーフローを引き起こしたようです。理由はわかりませんが、(mjhmが提案したように)古いオブジェクトから新しいNumberオブジェクトを作成するか、valueOf()を使用して数値をプリミティブに変換することで問題が解決しました。

元のNumberオブジェクトがどのようにスタックオーバーフローを引き起こしたかについて誰かが手がかりを持っているなら、私はあなたが提供しなければならないかもしれない洞察を非常に感謝します。

于 2012-12-26T21:47:06.707 に答える