Обработка ошибок мангуста с циклом forEach - PullRequest
0 голосов
/ 22 ноября 2018

У меня есть 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 после отправки заголовков клиенту.Как правильно обрабатывать .then и .catch с помощью цикла forEach?

Спасибо!

РЕДАКТИРОВАТЬ: я забыл добавить, что если я удалю .then и.catch запрос будет по-прежнему выполняться без ошибок.Но я бы хотел сохранить обработку ошибок в этом случае.

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

res.status(201).json находится в цикле forEach, поэтому вы получаете вышеуказанную ошибку: вы можете отправлять данные только один раз.

Чтобы это исправить, вам в основном нужно отправить операции 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 })
    })
}
0 голосов
/ 22 ноября 2018

Вы можете использовать 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
  })
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...