如何使用mongoose和bluebird promise确认更新是否成功

时间:2015-02-02 19:34:36

标签: javascript node.js mongodb promise bluebird

我正在使用bluebirdmongoose作为节点页面。 我想在通过socket.js将数据发送回客户端之前检查更新是否成功。以下是我无法弄清楚的代码部分:

.then(function(a) {
    var g = collection3.update({
        _id: a.one[0]._id
    }, {
        $set: {
            avg: a.one[0].avg
        }
    }).function(err, d) {
        if (!err) {
            return 1; // Here's the problem
        }
    }) return {
    updated: g,
    info: a
};
}).then(function(c) {
    console.log(c.updated); // I can't get the `1` value
    if (c == 1) {
        io.sockets.in('index|1').emit("estimate", c.three);
    }
})

更新后,mongoose会返回成功消息吗?我无法从更新查询返回1并将其传递给下一个函数,相反,我得到了这个对象:

{ _mongooseOptions: {},
  mongooseCollection:
   { collection:
      { db: [Object],
        collectionName: 'table',
        internalHint: null,
        opts: {},
        slaveOk: false,
        serializeFunctions: false,
        raw: false,
        pkFactory: [Object],
        serverCapabilities: undefined },
     opts: { bufferCommands: true, capped: false },
     name: 'table',
     conn:....

这是完整的代码:

  socket.on("input",function(d){ 
    Promise.props({
       one: collection2.aggregate([
        {
         $match:{post_id:mongoose.Types.ObjectId(d.id)}
        },
        {
         $group:{
                 _id:"$post_id",
                 avg:{$avg:"$rating"}
                }
        }
       ]).exec();
   }).then(function(a){     
      var g = collection3.update({_id:a.one[0]._id},{$set:{avg:a.one[0].avg}}).function(err,d){
        if(!err){
          return 1; // Here's the problem
        }
      })
      return {updated:g,info:a};
   }).then(function(c){
      console.log(c.updated); // I can't get the `1` value
      if(c.updated == 1){
        io.sockets.in('index|1').emit("estimate",c.three);
      }
   }).catch(function (error) {
     console.log(error);
   })

2 个答案:

答案 0 :(得分:2)

我假设您在这里使用Mongoose,update()是一个异步函数,您的代码是以同步方式编写的。

尝试:

   socket.on("input",function(d){ 
        Promise.props({
           one: collection2.aggregate([
            {
             $match:{post_id:mongoose.Types.ObjectId(d.id)}
            },
            {
             $group:{
                     _id:"$post_id",
                     avg:{$avg:"$rating"}
                    }
            }
           ]).exec()
       }).then(function(a){     
          return collection3.update({_id:a.one[0]._id},{$set:{avg:a.one[0].avg}})
          .then(function(updatedDoc){
            // if update is successful, this function will execute

          }, function(err){
            // if an error occured, this function will execute

          })

       }).catch(function (error) {
         console.log(error);
       })

答案 1 :(得分:2)

Mongoose docs说

  

Mongoose异步操作,如.save()和查询,返回   承诺/ A +符合承诺。这意味着你可以做的事情   像MyModel.findOne({})。then()和yield MyModel.findOne({})。exec()   (如果你正在使用co)。

另外 Mongoose Update返回更新的文档。

所以这看起来应该是这样的。

function runBarryRun(d) {
    Promise.props({
        one: aggregateCollection2(d)
    })
    .then(updateCollection3)
    .then(updatedDoc => {
        // if update is successful, do some magic here
        io.sockets.in('index|1').emit("estimate", updatedDoc.something);
    }, err => {
       // if update is unsuccessful, find out why, throw an error maybe
    }).catch(function(error) {
        // do something here
        console.log(error);
    });
}

function aggregateCollection2(d) {
    return collection2.aggregate([{
        $match: { post_id: mongoose.Types.ObjectId(d.id) }
    }, {
        $group: {
            _id: "$post_id",
            avg: { $avg: "$rating" }
        }
    }]).exec();
}

function updateCollection3(a) {
    return collection3.update({ _id: a.one[0]._id }, { $set: { avg: a.one[0].avg } }).exec();
}

socket.on("input", runBarryRun);