mongoose承诺链接不归还承诺

时间:2017-09-06 23:44:06

标签: javascript mongodb express mongoose promise

我的快速应用程序中有一个方法,使用mongoose findOneAndRemove()从mongoDB中删除照片。一切都很好,在我的承诺内,我调用一个辅助函数来更新数据库中的另一个文档。 我希望这个帮助函数在完成更新时返回一个promise。但是现在它在Category.updateMany({name:category},{$ set:{“count”:count}})之后停止; updateMany工作它只是没有通过链上的承诺。如何让我的updateCategories()方法从Category.updateMany()返回一个promise。

exports.deletePhoto = (req, res, next)=>{
  Photo.findOneAndRemove({_id:req.body.id})
  .then(photo => {
    S3.deleteS3File(photo.photo);
    updateCategories( photo.category ).then((result)=>{
      res.send(photo);
    });
  })
}


// helper method Updates categories with count number of photos.

function updateCategories( category ){
  return Photo.find({category:category.toLowerCase()})
  .then( results =>{
    var count = results.length;
    return Category.updateMany({name:category}, { $set: { "count" : count } } );
  })
}

更新说明: 我希望将updateCategories()方法保持独立,因为我在其他方法(如deletePhoto()等)中重复使用它。根据promises如何工作,您可以链接它们。所以我试图将它们链接起来,以便我从Category.updateMany()的最后一个承诺从updateCategories()函数返回。

我只是希望能够从多个函数调用我的以下updateCategories()帮助器方法,并让它从updateCategories中的Category.updateMany()返回一个承诺

updateCategories().then(result =>{
  // result 
)} 

最后更新 我只能通过一种方法获得所有承诺来实现这一目标。我不得不抛弃第二种方法的想法。这意味着重复代码但似乎无法使其工作。只是为了表明它与S3 deleteS3File方法无关。 以下代码基本上是realseanp建议的。

exports.deletePhoto = (req, res, next)=>{
  let photo;
  Photo.findOneAndRemove({_id:req.body.id})
  .then(p => {
    photo = p;
    S3.deleteS3File(photo.photo);
    return Photo.find({ category: p.category.toLowerCase() });
  })
  .then(results => {
     return Category.updateMany({ name: photo.category }, { $set: { "count": results.length } });
  }).then(() => {
     res.send(photo);
  }).catch(e => {
     console.log("ERROR COULD NOT DELETE PHOTO = ", e );
  });
}

1 个答案:

答案 0 :(得分:0)

你有一些承诺反模式的发生。将代码更新为以下代码将起作用

exports.deletePhoto = (req, res, next) => {
  let photo;
  Photo.findOneAndRemove({ _id: req.body.id })
    .then(p => {
      photo = p;
      S3.deleteS3File(photo.photo);
      return Photo.find({ category: photo.category.toLowerCase() });
    })
    .then(results => {
      const count = results.length;
      return Category.updateMany({ name: category }, { $set: { "count": count } });
    }).then(() => {
      res.send(photo);
    }).catch(e => { /* do something */ });
};

或者,如果您使用的是支持异步等待的节点版本,则可以使用以下

exports.deletePhoto = async (req, res, next) => {
  try {
    const photo = await Photo.findOneAndRemove({ _id: req.body.id });

    S3.deleteS3File(photo.photo);

    const catResults = await Photo.find({ category: photo.category.toLowerCase() });
    const count = catResults.length;

    await Category.updateMany({ name: category }, { $set: { "count": count } });

    return res.send(photo);
  } catch (e) {
    // There was an error - do something
  }
};

更新:

看起来updateMany方法返回一个查询 - 而不是一个promise。您必须执行查询才能获得承诺:

请注意,更新后的updateCategories函数现在使用exec()

exports.deletePhoto = (req, res, next) => {
  let photo;
  Photo.findOneAndRemove({ _id: req.body.id })
    .then(p => {
      photo = p;
      S3.deleteS3File(photo.photo);
      return updateCategories(photo.category.toLowercase());
    }).then(() => {
      res.send(photo);
    }).catch(e => { /* do something */ });
};

function updateCategories(category) {
  return Photo.find({ category })
    .then(results => Category.updateMany({ name: category }, { $set: { "count": results.length } }).exec());
}