首页 > 解决方案 > 如何连接通过 Node.js 中的 Mongoose 通过两个回调调用创建的字符串?

问题描述

我有两个相互关联的模型。如果第一个模型的 mongo 文档成功删除,我必须删除其父文档。

在尝试执行第二次删除时可能会引发异常。有错误或没有错误,我想连接第一条和第二条消息,但是“findOneAndDelete”中的“消息”变量的范围与其父级不同。

如何实现这个要求?

下面的代码片段可以正常工作,只是只传递了主要消息。

    var id = req.params.id;
    var valid = mongoose.Types.ObjectId.isValid(id);

    if (valid) {

        MyModel
        .findByIdAndDelete({"_id": id})
        .exec(function (err, result) {
            var message = "Item has been removed successful.";
            if (!result) {
                message = "Error at deleting an about item.";
            } else {

                // finding and deleting related about image item
                var query = { "id": id };

                SecondModel
                    .findOneAndDelete(query).exec(function (err, result) {

                    // deletion is OK, but the concatenation does not work
                    // how to return this "message" scope to its parent?

                    message += " Image item has been removed successful.";
                    if (!result) {
                        message += " Error trying to remove about image item.";
                    }

                });

            }

            // the concatenation should be returned here

            responseUtilities.sendJsonResponse(res, err, {"message": message});
        });
    } else {
        responseUtilities.sendJsonResponse(res, false, { "message": "Item id is not valid." });
    }



标签: javascriptnode.jsmongodbexpressmongoose

解决方案


很高兴你找到了答案。这里有一些结构和风格的想法,可以让代码更容易阅读(你将来或同事),并且更容易调试和扩展。首先为两个异步操作构建小的、返回承诺的函数。

function deleteAboutWithId(id) {
  return new Promise((resolve, reject) => {
    AboutModel.findByIdAndDelete({"_id": id}).exec(function (err, result) {
      err ? reject(err) : resolve(result)
    })
  })
}

function deleteImageWithAboutId(id) {
  return new Promise((resolve, reject) => {
    AboutImageModel.findOneAndDelete({ aboutId: id }).exec(function (err, result) {
      err ? reject(err) : resolve(result)
    })
  })
}

这些的一个很好的好处是它们可以进行单元测试、重用、泛化等。另一个好处是使用它们使您的业务逻辑清晰简洁。代码读取您向同事描述函数的方式......

  • 删除项目
  • 删除图像
  • 如果两者都成功,则回答复合成功消息
  • 如果任一失败,请回答(可能)复合错误消息

公共功能:

const msgIdError = 'About item id is not valid.'
const msgItemSuccess = 'About item has been removed successful.'
const msgImageSuccess = ' Its image item has also been removed successful.'
const msgItemError = 'Error at deleting an about item.'
const msgImageError = ' Error trying to remove about image item.'

module.exports.delete = function (req, res) {
  const idAbout = req.params.idAbout
  if (!mongoose.Types.ObjectId.isValid(idAbout)) {
    responseUtilities.sendJsonResponse(res, false, { "message": msgIdError })
  }
  let message = ''
  deleteAboutWithId(idAbout).then(() => {
    message += msgItemSuccess
    return deleteImageWithAboutId(idAbout)
  }).then(() => {
    message += msgImageSuccess
    responseUtilities.sendJsonResponse(res, err, { "message": message })
  }).catch(err => {
    // if message is empty, the first block threw the error
    message += message.length ? msgImageError : msgItemError
    responseUtilities.sendJsonResponse(res, err, { "message": message });
  })
}

几个快速说明:(1)很高兴将字符串移开。这些可能有一天会保存在配置中,翻译成其他语言等。(2)它会稍微清理代码以检查顶部的无效输入,如果输入无效,则在顶部退出。


推荐阅读