如何使用mongoose本机承诺(mpromise)删除文档,然后更新另一个文档

时间:2015-05-13 05:12:58

标签: angularjs node.js mongoose promise

我正在尝试使用promises来避免深层嵌套回调。我有以下代码:

exports.destroy = function(req, res) {
  var actionID = req.body.id;

  var promise = Action.findById(actionID).exec();
  promise.then(function (action) {
    return Action.remove({'_id': action.id}).exec();
  }).then(function (count, action, something) {
    debugger;
  });
};

我的操作文档Schema包含引用子操作的ObjectID数组:

var ActionSchema = new Schema({
  title: String, // Text to be shown when creating new action
  description: String, // Description if any
  children: { type: [Schema.Types.ObjectId], default: [] }, // JSON.stringified list of children
  nest_level: Number, // how nested we are for children level
});

我要做的是删除一个操作文档,当该操作文档完成并成功时,查找与已删除操作相关联的所有操作文档(通过子字段),并删除已删除的操作&# 39;来自' children'的ObjectID阵列。

在调试器部分,count返回已删除文档的数量,action似乎是一个空字符串,并且没有返回任何其他内容('某些'变量未定义)。

我有两个问题:

  • 我如何在一个mongoose承诺中解决或拒绝承诺?互联网上没有太多信息要遵循(通常它是一般承诺教程)。
  • 如果Action.remove()。exec()没有返回已删除文档的副本,我将如何进行其他查询以实际更新其他文档?

1 个答案:

答案 0 :(得分:1)

您可以使用findByIdAndRemove来简化第一步(为什么要进行两次数据库请求?)。如果成功,已解决的承诺将是删除的文档。

exports.destroy = function(req, res) {
  var actionID = req.body.id;

  Action.findByIdAndRemove(actionID).exec().then(function(action) {
    // action.children 
  }).then(null, function(err) {
    // Do something with the error.
  });
};

从那里你需要管理从子列表中删除操作。执行此操作的解决方案包括asyncqbluebird或者您是否只想继续使用承诺(如果有很多孩子,您就不在乎管理负载或递归删除子项)您可以使用较新版本的节点中提供的内置Promise对象。

exports.destroy = function(req, res) {
  var actionID = req.body.id;

  Action.findByIdAndRemove(actionID).exec().then(function(action) {
    return Promise.all(action.children.map(function(id) {
      Action.findByIdAndRemove(id).exec();
    })); // returns promise
  }).then(function (results) {
    // results will be an array of child docs removed.
    // NOTE: this isn't recursive
  }).then(null, function(err) {
    // Do something with the error.
  });
};

要使其递归(再次没有负载管理),需要进行一些重构。类似的东西:

exports.destroy = function(req, res) {
  destroy(req.body.id).then(function (results) {
    // results will be a multi-dimesional array if children are removed
    // response
  }).then(null, function (err) {
    // error response
  });
};

function destroy(actionID) {
  return Action.findByIdAndRemove(actionID).exec().then(function(action) {
    return Promise.all(action.children.map(function(id) {
      return destroy(id);
    })); // returns promise
  });
}

注意:此代码均未经过测试