猫鼬阻止下一个then()被执行

时间:2019-05-05 11:16:37

标签: node.js mongoose promise

使用猫鼬,我将任务保存到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
          }
        }
      })
    })
})

2 个答案:

答案 0 :(得分:0)

    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 }) 
                   }
                   return Board.findByIdAndUpdate(boardId, 
                   {
                        lastTaskNumber: newTaskNumber, 
                        $push: { 
                             'columns.0.tasks': {
                                  taskId: newTaskId,
                                  title: task.title, 
                                  priority: task.priority 
                              } 
                        } 
                   }) 
             }, 
             { _id: false } ) 
        })
       // *********
       //if the above fails, don't execute the next then()
      // ********* 
      .catch(() => console.log('error saving a task')) 

结构已更改,但应该这样做

答案 1 :(得分:0)

下面是注释中建议的async/awaittransactions的猫鼬的工作示例。

正在按顺序调用这些调用,在完成前一个调用之后开始下一个调用。通过使用事务,所有异步函数只有一个catch。如果其中一个调用失败,则将从数据库中还原所有先前的更改,并调用catch

taskRouter.post('/:boardId', (req, res) => {
  let task = new Task(req.body)
  let boardId = req.params.boardId
  let newTaskNumber
  let newTaskId

    // tslint:disable-next-line
  ;(async function addTask() {
    const session = await mongoose.startSession()
    session.startTransaction()

    try {
      await Board.findById(boardId, null, { session })
        .select('lastTaskNumber -_id')
        .exec()
        .then(board => {
          newTaskNumber = board.lastTaskNumber + increaseTaskNumberBy
          newTaskId = `${boardId}-${newTaskNumber}`
          task._id = newTaskId
        })

      await Task.create([task], { session }, null, {
        _id: false
      })

      await Board.findByIdAndUpdate(
        boardId,
        {
          lastTaskNumber: newTaskNumber,
          $push: {
            'columns.0.tasks': {
              taskId: newTaskId,
              title: task.title,
              priority: task.priority
            }
          }
        },
        { session }
      )

      await session.commitTransaction()
      session.endSession()
      return res.status(200).json(task)
    } catch (error) {
      await session.abortTransaction()
      session.endSession()
      return res.status(400).json({
        message: 'Error saving a new task',
        error: error
      })
    }
  })()
})