迭代Mongoose结果以更新值

时间:2015-04-10 06:59:18

标签: node.js mongodb mongoose mongodb-query

我对此有点新鲜,所以如果我在完全错误的轨道上,请随时告诉我。

我有以下帖子架构。

var Post = new Schema( {
    description: {
        type: String,
        default: '',
        required: 'Please type a description',
        trim: true
    },
    likeCount: {
        type: Number,
        default: 0
    },
    url: {
        type: String,
        default: '',
        required: 'Unable to find photo',
        trim: true
    },
    created: {
        type: Date,
        default: Date.now
    },
    user: {
        type: Schema.ObjectId,
        ref: 'User',
        required: 'Unable to verify user'
    },
    comments: {
        type: [Comment]
    },
    //Dynamically added values
    hasLiked: {
        type: Boolean
    }
});

以下是Like schema

var Like = new Schema({
    created: {
        type: Date,
        default: Date.now
    },
    user: {
        type: Schema.ObjectId,
        ref: 'User'
    },
    post: {
        type: Schema.ObjectId,
        ref: 'Post'
    }
});

当我向用户显示帖子列表时,我需要指出他们之前是否“喜欢”过帖子,所以我试图拉动帖子,然后通过它们进行迭代以确定此人是否喜欢它并更新邮政中的价值。我没有收到任何错误,但它也没有更新hasLiked值。我将hasLiked值放入我的Mongoose模型中,因为我不能在返回结果之前动态添加值。我没有在DB中存储实际值,因为对于每个查看帖子的人来说,显然会有所不同。

exports.list = function(req, res) {
    Post.find().sort('-created').populate('user', 'displayName')

        .exec(function (err, posts) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {

            for (var i = 0; i < posts.length; i++) {

                Like.find({ 'post': posts[i]._id, 'user': req.user.id }).exec(function (err, like) {
                    if (err) {
                        return res.status(400).send({
                            message: errorHandler.getErrorMessage(err)
                        });
                    } else {
                        if (like.length == 0)
                            posts[i].hasLiked = false;
                        else
                            posts[i].hasLiked = true;
                    }

                });

            }
            res.jsonp(posts);
        }
    });
};

1 个答案:

答案 0 :(得分:5)

Node是异步语言。所以你的错误在于,当你查询以查找用户是否喜欢这个帖子时:

Like.find({ 'post': posts[i]._id, 'user': req.user.id }).exec(function (err, like)

答案将在之后返回,您将答案返回给客户端。换句话说,在mongo的回答返回并进入回调之前执行的行res.jsonp(posts);。这就是为什么它不适合你。

要处理异步方法,建议您使用第三方库,例如asyncq。 以下是Q库的一个解决方案:

var Q = require('q');

var promises = [];
posts.forEach(function(post) {
  promise = Q(Like.find({ 'post': post._id, 'user': req.user.id }).exec())
    .then(
      function(like) {
          if (like.length == 0)
                post.hasLiked = false;
          else
                post.hasLiked = true;
          }
      }  
      ,function(err) {
         //handle error
    });
})

Q.all(promises)
  .then(function() {
      return res.jsonp(posts);
  });