【问题标题】:mongoose promise chaining not returning promise猫鼬承诺链接不返回承诺
【发布时间】:2018-02-15 13:39:43
【问题描述】:

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

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() 等其他方法中重用它。根据承诺的工作方式,你可以链接它们。所以我试图链接它们,以便我从 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 );
  });
}

【问题讨论】:

  • 是的,你在deletePhoto函数或回调函数中没有return任何东西。
  • 停止”同时又“一切正常”到底是什么意思?到底发生了什么?您是否可能在某处遇到错误(我注意到您没有.catch()ing 任何拒绝)?
  • 没有发生错误。通过停止,我的意思是我的 updateCategories() 函数没有返回承诺。我想做的就是从 Category.updateMany() 中返回承诺
  • 你确定吗?它还返回什么?如果它没有返回一个 Promise,你应该会得到一个关于无法在返回值上调用 then 方法的错误。
  • updateCategories的then部分没有运行。

标签: javascript mongodb express mongoose promise


【解决方案1】:

你有一些承诺反模式正在发生。将您的代码更新为以下内容即可

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 方法返回一个查询 - 而不是一个承诺。您必须执行查询才能获得承诺:

注意更新后的 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());
}

【讨论】:

  • 再一次,不要忘记return 承诺或.catch() 里面的任何错误。
  • deletePhoto 似乎是一个快速路由回调函数 - 它不需要返回任何内容,但是应该添加一个 catch 函数。
  • @Bergi 添加了 catch ?
  • S3.deleteS3File(photo.photo); 实际上是异步方法本身的可能性有多大?在我看来,这是问题中代码的“真正突出”问题。剩下的只是语义。清洁器!但仍然是语义的。
  • @realseanp 谢谢。鉴于它看起来像一个快速回调函数,您可能需要调用 next(err)
猜你喜欢
  • 2019-06-04
  • 2019-02-13
  • 2018-08-19
  • 2015-05-12
  • 2023-01-27
  • 2018-09-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
相关资源
最近更新 更多