如何确保代码不会在promise之后运行



我有一段代码,其中运行了2个promise。

问题是第二个promise在运行,而第一个promise仍在运行。这给我带来了很多问题。我希望第二个承诺不会兑现,直到我得到第一个承诺的答案。

我不想把第二个承诺放在第一个承诺里面。

有人知道我怎样才能做到这一点?是否可以使用异步等待?

这是我的代码:

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);
});
});

非常感谢!

我不想把第二个承诺放在第一个承诺里面。

嗯。。。这就是你所做的,有效地:

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);
}
});

这里有一个使用async/await的版本。令人惊讶的是,它使事情变得平坦,并简化了错误处理。catch将捕获waiting(抛出或拒绝(和方法本身中抛出的所有异常。

此外,您不想在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)
}
});

最新更新