我有一个带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
,查询将仍然运行,并且没有错误。但是在这种情况下,我想保留错误处理。
答案 0 :(得分:1)
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 })
})
}
答案 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
})
};