javascript - 如何连接通过 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." });
}
解决方案
很高兴你找到了答案。这里有一些结构和风格的想法,可以让代码更容易阅读(你将来或同事),并且更容易调试和扩展。首先为两个异步操作构建小的、返回承诺的函数。
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)它会稍微清理代码以检查顶部的无效输入,如果输入无效,则在顶部退出。
推荐阅读
- java - 协调器布局无法转换为 android.support.v7.widget.Toolbar 错误使应用程序崩溃
- redis - 多用户中与 Composer 的 Web 应用交互
- javascript - 输入按钮未使用 select2 和 X-editable 提交
- vuejs2 - javascript - 在 vuejs2 模板中打开链接作为新窗口
- .net - Selenium .NET HtmlUnitDriver 无法连接到远程服务器
- android - Android Studio 重命名包 - Bitbucket 和 Git 管理
- google-apps-script - 从验证列表中删除已被选中的项目
- android - 在 Facebook 上共享项目,我在 Manifest.xml 文件中收到错误
- linux - 出现错误:将备份还原到 5.x Greenplum DB 时无法识别配置参数“gp_strict_xml_parse”
- mfc - 如何捕捉对话框的移动事件?