Nodejs RangeError:超出最大调用堆栈大小,由响应中的发送对象引起

时间:2016-07-13 17:02:06

标签: node.js express

如果有人能帮我解决这个问题,那真是太棒了。

我目前遇到一个问题,调用此快速路由会给我一个RangeError下面的错误显示:超出最大调用堆栈大小

当我包含res.json(users [user])时,似乎只会发生这种情况。功能。如果我用res.send代替这个函数('完成');功能运行正常。

我已经尝试了setTimeout,setImmediate和process.nextTick,所有这些都给了我同样的错误,就在这里。

我希望我的结果是一个愚蠢的错误。

//Send Friend Request
router.post('/send/friend/request', auth, function(req, res, next){

 var query = User.find({$or: [
  {username: req.body.username},
  {username: req.payload.username}
 ]})
 .select(' username friends notifications');

 query.exec(function(err, users){
  if(err) return next(err);
  if(users.length < 2) console.log('/send/friend/request - There was an error      in accessing the users from the db');
  else{

   //Identify users in array
   var user = users.findIndex(function(element, index){
    if(element.username === req.payload.username)
      return element;
    });
   var requestUser = (user + 1) % 2;

   //addFriends
   users[user].friends.push({
     user: users[requestUser],
   });

   users[requestUser].friends.push({
     user: users[user],
     sent: false
   });

   //notifications
   users[user].notifications.push({ 
     user: users[requestUser],  
     type: 0, 
     summary: "Your friend request has been sent to " + req.body.username +".",
     status: "Pending..."
   });

   users[requestUser].notifications.push({
     user: users[user],  
     type: 1, 
     summary: "You have a new friend request from " + req.payload.username + ".",
     status: "Pending..."
   });

   users[requestUser].save(function(err){
     if(err) return next(err);
   });

   users[user].save(function(err){
    if(err) return next(err);
   });

     //Here lies the culprit
     res.json(users[user]);
  }
 });
});

3 个答案:

答案 0 :(得分:1)

您正在users[user]users[requestUser]之间创建循环引用。

以下是演示此问题的示例:

const mongoose = require('mongoose');
const Schema   = mongoose.Schema;

const userSchema = Schema({ friends : [] });
const User       = mongoose.model('User', userSchema);

let user1 = new User();
let user2 = new User();

user1.friends.push(user2); 
user2.friends.push(user1); // the circular reference is created here

console.log( JSON.stringify(user1) );

JSON.stringify()会因为循环引用而抛出RangeError

您可能需要重新考虑您的架构,因为我认为您不能将subdocs用于您的目的。相反,您应该使用"population"来存储文档之间的引用。

当您将上面的架构更改为以下内容时,它不会抛出:

const userSchema = Schema({
  friends : [ { type : Schema.Types.ObjectId, ref : 'User' } ]
});

编辑:如果您使用复杂对象作为数组内容,即使使用填充,也应该推送_id值,而不是文档:

users[user].friends.push({
  user: users[requestUser]._id,
});

答案 1 :(得分:0)

也许

如果user自身包含引用,则res.json会失败。因为req.json试图爆炸unlimited对象。要避免此问题,您可以:

  1. 指定要发送的用户字段

    res.send(JSON.stringify(user, ['name', 'age', ...]))

  2. 将引用定义为不可枚举的属性

    Object.defineProperty(user, 'your-ref', {enumerable: false});

答案 2 :(得分:0)

绝对对象users不是JSON.Its POJO对象具有额外的mongo属性,其中包含对__proto__属性的递归referance。

执行序列化,然后再次在客户端进行反序列化。

或者在新的Object literal中提取属性,然后传递给它resp.json()