使用forEach循环处理猫鼬时出错

时间:2018-11-22 14:27:29

标签: node.js mongodb mongodb-query

我有一个带express的mongodb,执行以下操作时出现Cannot set headers after they are sent to the client. Unhandled promise rejections are deprecated错误。

exports.deleteBooking = (req, res, next) => {
  req.body.courts.forEach(element => {
    Booking.deleteOne({$and: [
      { cid: element.cid },
      { year: element.day.year }
    ]})
    .then(result => {
      res.status(201).json({
        message: result
      });
    })
    .catch(() => {
      res.status(500).json({
        error: 'error'
      })
    });
  })
};

我正在向服务器发送一组对象,并希望对每个对象执行一次删除。

由于forEach,它可能在将标头发送到客户端之后运行.catch。用forEach循环处理.then.catch的正确方法是什么?

谢谢!

编辑:我忘了补充一点,如果我删除.then.catch,查询将仍然运行,并且没有错误。但是在这种情况下,我想保留错误处理。

2 个答案:

答案 0 :(得分:1)

res.status(201).jsonforEach循环内,因此为什么会出现上述错误:您只能发送一次数据。

要解决此问题,您基本上需要发送一次deleteOne操作并使用 bulkWrite() ,因为它允许您通过一个命令将多个deleteOne操作发送到MongoDB服务器。 。它以对象数组的形式接受输入,如下所示:

Booking.bulkWrite([
    { deleteOne: { filter: { cid: 1, year: 2007 } } },
    { deleteOne: { filter: { cid: 2, year: 2007 } } },
    { deleteOne: { filter: { cid: 3, year: 2007 } } },
    { deleteOne: { filter: { cid: 4, year: 2007 } } }, 
])

因此,您可以将req.body.courts数组映射为上述deleteOne操作,

exports.deleteBooking = (req, res, next) => {
    Booking.bulkWrite(
        req.body.courts.map(({ cid, day }) => ({
            deleteOne: { filter: { cid, year: day.year } }
        }))
    ).then(message => {
        res.status(201).json({ message })
    }).catch(error => {
        res.status(500).json({ error })
    })
}

答案 1 :(得分:0)

您可以使用Promise.all代替forEach

exports.deleteBooking = (req, res, next) => {
  const promises = req.body.courts.map(element => 
    Booking.deleteOne({$and: [
      { cid: element.cid },
      { year: element.day.year }
    ]})
  );

  Promise.all(promises).then((results) => {
    // Handle the result response
  })
  .catch((error) => {
    // Handle the error response
  })
};