如何让快速路由在向客户端发回响应之前做两件事?

How to make an express route do 2 things before sending back a response to the client?

我试图在 express route 内完成各种事情,简而言之,我有这条路线 /checkNsguid,我可以在其中提交表格。我希望路线执行以下操作:

  1. 验证 nguid 代码是否有效(它存在于数据库中)。
  2. 如果找到有效的 nguid code,它会将一些字段从 NGUID table 复制到 ModelTable(它更新模型对象)
  3. 它将 更新的 模型对象发回客户端应用程序。

出于某种原因,我仍在取回旧模型对象。我可以看到它在 db 上更新了有效字段,但 res.send(...) 仍然向我发送旧对象。

我不知道这是我使用 Promises 的方式,使用 next() 还是我遗漏的其他方式。如果有人能给我指出正确的方向,请问?

谢谢

/**
 * Check if nguidCode is in the list
 *
 * @return {JSON}
 */
router.post(
  '/checkNguid',
  (req, res, next) => {
    let modelID = req.body.modelID
    let nguid = req.body.nguid

    // 1. Step 1
    // Goes to the CheckNGUID table
    // maps through all the collections until it finds one that matches 
    // the  submitted nguidcode
    // verifies that the code is valid and if so then copies various 
    // fields to the ModelTable via `.updateInfosFromOldDb`

    // After that I don't want anything else to do with that response obj.
    // I want to "pass" control to Step 2 

    nguidCode
      .checkNguid(nguid)
      .then((response) => {
        console.log('this is the response inside backend', response)

        response.length === 0
          ? res.status(400).json({ result: 'nok', error: 'Invalid nguidCode' })
          : response.map((el) =>
            // [NOTE]: Updates the model object with the nguid info if found
              modelModel.updateInfosFromOldDb(
                modelID,
                nguid,
                el.rate,
                el.subscribedAt,
              ),
            )
          next()


        // console.log('this is the response inside backend 2', response)
        // res.status(200).json({ result: 'ok', model: response })
        // res.status(200).json({ result: 'ok', model: response })
      })
      .catch((error) => {
        res.status(400).json({ result: 'nok', Error: error.toString() })
      })
  },

  // 2. Step 2
  // This is the updated model obj I would like to send back to the client app.

  // [ASK]: I want to send back the updated model Object,
  // However I'm still getting back the old one.
  (req, res) => {
    modelModel.getByID(req.body.modelID).then((response) => {
      console.log('response inside the next()', response)
      res.status(200).json({ result: 'ok', model: response })
    })
  },
)

updateInfosFromOldDb

const updateInfosFromOldDb = (modelID, nguid, rate, subscribedAt) => {

  return new Promise((resolve, reject) => {
    ModelModel.findOne({ id: modelID }, (err, model) => {
      if (err) {
        reject(err);
      }
      model.nguidCode= nguid
      model.rate= rate
      model.subscribedAt =subscribedAt
      //model.payments.push(paymentId);

      model.save((err, response) => {
        if (err) {
          reject(err)
        } else {
          resolve(response)
        }
      })
    })
    
  });

}

您收到旧响应,因为 next()nguidCode.checkNguid 承诺解决之前被调用,即在您的数据库调用完成之前。为了解决这个问题,我们需要在 then() 块内移动 next() -

/**
 * Check if nguidCode is in the list
 *
 * @return {JSON}
 */
router.post(
  '/checkNguid',
  (req, res, next) => {
    let modelID = req.body.modelID
    let nguid = req.body.nguid

    // console.log(req.body, 'req.body in the backend')

    nguidCode
      .checkNguid(nguid)
      .then((response) => {
        console.log('this is the response inside backend', response)
        if(response.length === 0) {
          throw new Error('Invalid nguidCode');
        } else {
          // Wrapping list of promises in Promise.all so that then() callback is invoked once all
          // promises are resolved
          return Promise.all(response.map((el) =>
          // [NOTE]: Updates the model object with the nguid info if found
            modelModel.updateInfosFromOldDb(
              modelID,
              nguid,
              el.rate,
              el.subscribedAt,
            ),
          ))
        }
        // console.log('this is the response inside backend 2', response)
        // res.status(200).json({ result: 'ok', model: response })
        // res.status(200).json({ result: 'ok', model: response })
      })
      .then((data) => {
        return next()
      })
      .catch((error) => {
        return res.status(400).json({ result: 'nok', Error: error.toString() })
      })
    // [NOTE]: This also works I go onto the modelModel.getByID(...)
  },

  // [ASK]: I want to send back the updated model Object,
  // However I'm still getting back the old one.
  (req, res) => {
    modelModel.getByID(req.body.modelID).then((response) => {
      console.log('response inside the next()', response)
      return res.status(200).json({ result: 'ok', model: response })
    })
  },
)