【发布时间】:2019-09-23 06:32:44
【问题描述】:
使用 Mongoose,我将任务保存到 task 集合中,如果进展顺利,应该使用任务数据更新板。但是,如果上一个(保存任务)出错,我不知道如何防止执行最后一个then()(保存到板)。
我一直在尝试使用Promise.reject(),但我不确定如何返回Promise.reject() 和错误的响应状态。
// POST add a new task
taskRouter.post('/:boardId', (req, res) => {
let task = new Task(req.body)
let boardId = req.params.boardId
let newTaskNumber
let newTaskId
// get lastTaskNumber from the board
Board.findById(boardId)
.select('lastTaskNumber')
.exec()
.then(board => {
newTaskNumber = board.lastTaskNumber + increaseTaskNumberBy
newTaskId = `${boardId}-${newTaskNumber}`
task._id = newTaskId
return
})
// save the task in the task collection
.then(() => {
return task.save(
(err, task) => {
if (err) {
return res.status(400).json({
message: 'Error saving a task',
error: err
})
} else {
res.status(200).json(task)
}
},
{ _id: false }
)
})
// *********
//if the above fails, don't execute the next then()
// *********
.catch(() => console.log('error saving a task'))
// update lastTaskNumber in the board
// add task to the 1st column of the board
.then(() => {
return Board.findByIdAndUpdate(boardId, {
lastTaskNumber: newTaskNumber,
$push: {
'columns.0.tasks': {
taskId: newTaskId,
title: task.title,
priority: task.priority
}
}
})
})
})
【问题讨论】:
-
这不是进行多文档操作的正确方法。如果执行这些操作相互依赖,则需要使用 mongodb 事务。查看相同的文档。 docs.mongodb.com/master/core/transactions/…
-
写得有点混乱,而且可能不正确,因为有一个外部
task和一个内部task。您想要task.title和task.priority的位置尚不清楚您希望这些是外部属性还是内部task的属性。正如所写,它是外部的。 -
@cEeNiKc,我正在努力解决这里的交易需求。你能帮我解释一下吗?
-
请参阅 mongodb 提供了对单个文档进行操作的原子性,即,如果您正在更改单个文档的 4 个字段,您可以确保所有这些更改都将被保存,或者它们都不会被保存。但是在您的情况下,您想要创建一个任务,然后如果它创建时没有任何错误,您想要更新不同 Boards 集合中的文档。对于这个用例,您需要使用 mongodb 事务,这将确保所有更改都被保存或都不保存。如果你可以请使用新的异步等待语法和 try catch 块,它会让你的代码更好。
-
这是一篇非常好的关于在猫鼬中使用事务的博文。看看这个,它会让事情更清楚。 thecodebarbarian.com/…