我有一段代码,其中我有2个诺言。
问题是第二个承诺在第一个承诺仍在运行时运行。这给我造成了很多问题。 我希望第二个承诺不会执行,直到我从第一个承诺得到答复。
我不想把第二个诺言放在第一个诺言中。
有人知道我该如何实现?可以使用异步等待吗?
这是我的代码:
router.post("/", (req, res) => {
if (!checkIfOrderValid(req.body)) {
return res.sendStatus(400);
}
let order = new Order(req.body);
order._UserId = '5b58836ed741e92d7416002e';
//first check if the seats are taken
/*
this is working. but gives me
"(node:14552) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): Error: Can't set
headers after they are sent."
when the seats are taken. check it out
*/
Show.findById(req.body._ShowId).then(show => {
req.body.ticketsPositions.forEach(element => {
console.log('checking: ' + element[0] + "-" + element[1]);
if (show.showTakenSeats.hasOwnProperty(element[0] + "-" + element[1])){
console.log('seat are already taken!');
return res.status(400).json({'message': 'Seats are already taken!'})
}
});
});
order.save().then(newOrder => {
console.log("Order saved successfully");
res.json(newOrder);
}, err => {
res.send(err);
});
});
非常感谢!
答案 0 :(得分:4)
我不想把第二个诺言放在第一个诺言中。
嗯...这就是您要做的,有效地:
router.post("/", (req, res) => {
if (!checkIfOrderValid(req.body)) {
return res.sendStatus(400);
}
let order = new Order(req.body);
order._UserId = '5b58836ed741e92d7416002e';
Show.findById(req.body._ShowId)
.then(show => {
// Make sure all seats are okay; notice we don't do `res.send` here,
// we just see if every seat is available
const seatsOkay = req.body.ticketPositions.every(element => {
console.log('checking: ' + element[0] + "-" + element[1]);
return !show.showTakenSeats.hasOwnProperty(element[0] + "-" + element[1]);
});
if (seatsOkay) {
// Yes, order
return order.save().then(newOrder => {
console.log("Order saved successfully");
res.json(newOrder);
});
} else {
// Nope, send response -- ONCE, not in the ticketPositions loop
console.log('seat are already taken!');
res.status(400).json({'message': 'Seats are already taken!'})
});
})
.catch(err => {
res.send(err);
});
});
在任何模糊的现代版本的Node上,都可以使用async
函数。只需确保捕获错误,因为router.post
不会为您处理错误(您可能会看到koa):
router.post("/", async (req, res) => {
try {
if (!checkIfOrderValid(req.body)) {
return res.sendStatus(400);
}
let order = new Order(req.body);
order._UserId = '5b58836ed741e92d7416002e';
// Get this show
const show = await Show.findById(req.body._ShowId);
// Make sure all seats are okay
const seatsOkay = req.body.ticketPositions.every(element => {
console.log('checking: ' + element[0] + "-" + element[1]);
return !show.showTakenSeats.hasOwnProperty(element[0] + "-" + element[1]);
});
if (seatsOkay) {
// Yes, order
const newOrder = await order.save();
console.log("Order saved successfully");
res.json(newOrder);
} else {
// Nope, send error response
console.log('seat are already taken!');
res.status(400).json({'message': 'Seats are already taken!'})
});
} catch (err) {
res.send(err);
}
});
答案 1 :(得分:3)
这是使用async / await的版本。令人惊讶的是,它使事情变得平整,并简化了错误处理。捕获将捕获所有等待(抛出或拒绝)中的所有异常,并抛出该方法本身。
此外,您也不想扔进forEach。使用过滤器代替查找要查找的条件。如果您需要循环中的异步内容,那完全是另一个问题。
router.post("/", async(req, res) => {
try {
if (!checkIfOrderValid(req.body)) {
return res.sendStatus(400);
}
let order = new Order(req.body);
order._UserId = '5b58836ed741e92d7416002e';
var show = await Show.findById(req.body._ShowId)
var taken = req.body.ticketsPositions.find(element => {
return show.showTakenSeats.hasOwnProperty(element[0] + "-" + element[1])
});
if (taken) {
return res.status(400).json({
'message': 'Seats Taken'
})
}
var newOrder = await order.save().json()
res.send.json(newOrder);
} catch (err) {
res.status(500).send(err)
}
});