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 ] } ...

我始终没有错误和正确的地方。如果我避免调用coordFinderingetCoords并更改getCoords

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

我知道该错误表明堆栈溢出(增加堆栈大小没有帮助),但我不知道我是如何造成的。有谁知道为什么会发生这种情况?提前感谢您的见解!

编辑mongodb-native:顺便说一句,直接使用时遇到了同样的问题,所以mongoose似乎不是问题。另一个线索 - 当我不在回调中调用它时,使用相同的查询永远不会给我带来问题。这可能是错误的来源吗?

我用

  • 节点.js 0.6.14
  • MongoDB 2.2.2
  • 节点模块异步 0.1.22
  • 节点模块 mongodb 1.2.5
  • 节点模块猫鼬2.5.7

干杯,乔治

4

2 回答 2

2

问题很可能来自async.forEachSeries. 尝试用这样的方式包装Places.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 为我指明了正确的方向。显然,传递给 mongoose 查询的 Number 实例导致了堆栈溢出。我不知道为什么,但是从旧的数字对象创建一个新的数字对象(如 mjhm 建议的那样)或使用 valueOf() 将数字转换为原语解决了这个问题。

如果有人知道原始 Number 对象是如何导致堆栈溢出的,我将非常感谢您提供的任何见解。

于 2012-12-26T21:47:06.707 回答