使用Mongoose承诺进行查找和更新

时间:2014-05-07 09:20:05

标签: node.js mongoose promise

我正在尝试使用Mongoose Promises来获得更清晰的代码(请参阅嵌套函数)。 具体来说,我正在尝试构建这样的东西:

Model.findOne({_id: req.params.id, client: req.credentials.clientId}).exec()
   .then(function(resource){
      if (!resource) {
        throw new restify.ResourceNotFoundError();
      }
      return resource;
    })
    .then(function(resource) {
      resource.name = req.body.name;
      return resource.save; <-- not correct!
    })
    .then(null, function(err) {
       //handle errors here
    });

所以,在其中一项承诺中,我需要保存我的模型。从最新的稳定版本开始,Model.save()不返回promise(bug为here)。

要使用经典的保存方法,我可以使用它:

   //..before as above
   .then(function(resource) {
      resource.name = req.body.name;
      resource.save(function(err) {
        if (err)
            throw new Error();
        //how do I return OK to the parent promise?
      });
    })

但是在代码中也有注释,如何将保存回调(运行异步)的返回值返回到保留承诺?

有更好的方法吗?

(顺便说一下,findOneAndUpdate对我来说是一个禁忌的解决方案)

1 个答案:

答案 0 :(得分:1)

这样做的一种方法是将.save代码包装在您自己的方法中,该方法返回一个promise。你需要一个承诺库,比如RSVP或Q.我会用RSVP写的,但你应该明白这个想法。

var save = function(resource) {
  return new RSVP.Promise(function(resolve, reject) {
    resource.save(function(err, resource) {
      if (err) return reject(err);
      resolve(resource);
    });
  });
}

然后在你的主叫代码中:

// ...

.then(function(resource) {
  resource.name = req.body.name;
  return save(resource);
})
.then(function(resource) {
  // Whatever
})
.catch(function(err) {
 // handle errors here
});

另一种方法是将节省方法用于节点化,但我会按照上面详述的方式进行。