遍历 Mongoose 结果以更新值

Iterate through Mongoose results to update value

我对此有些陌生,所以如果我走错了路,请随时告诉我。

我有以下 post 架构。

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 架构

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

当我向用户显示 post 的列表时,我需要指出他们之前是否有 "liked" 个 post,所以我试图拉出 posts,然后遍历它们以确定此人是否喜欢它并更新 Post 中的值。我没有收到任何错误,但它也没有更新 hasLiked 值。我将 hasLiked 值放入我的 Mongoose 模型中,因为我不能在返回结果之前即时添加一个值。我没有在数据库中存储实际值,因为每个查看 post.

的人显然都不同
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);
        }
    });
};

节点是异步语言。所以你的错误是,当你查询用户是否喜欢 post:

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

答案将return您return答案后交给客户。换句话说,行 res.jsonp(posts); 在 mongo return 的答案之前执行并进入回调。这就是它对您不起作用的原因。

要处理异步方法,我建议您使用第三方库,例如async or q。 这是 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);
  });