Javascript 如何确保代码不会在承诺后运行?
我有一段代码,其中我运行了两个承诺 问题是,第二个承诺在第一个承诺仍在运行时运行。这给我带来了很多问题。 我希望第二个承诺不会兑现,直到我得到第一个承诺的答复 我不想把第二个承诺放在第一个承诺里面 有人知道我怎样才能做到这一点?可以使用异步等待吗 这是我的密码:Javascript 如何确保代码不会在承诺后运行?,javascript,node.js,ecmascript-6,async-await,es6-promise,Javascript,Node.js,Ecmascript 6,Async Await,Es6 Promise,我有一段代码,其中我运行了两个承诺 问题是,第二个承诺在第一个承诺仍在运行时运行。这给我带来了很多问题。 我希望第二个承诺不会兑现,直到我得到第一个承诺的答复 我不想把第二个承诺放在第一个承诺里面 有人知道我怎样才能做到这一点?可以使用异步等待吗 这是我的密码: router.post("/", (req, res) => { if (!checkIfOrderValid(req.body)) { return res.sendStatus(400); }
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
不会为您处理错误(您可能会看到):
下面是一个使用async/await的版本。令人惊讶的是,它如何使事情变得平坦,并简化了错误处理。catch将捕获等待(抛出或拒绝)和方法本身中抛出的所有异常 另外,你也不想把它扔进一个forEach里面。使用过滤器来查找您要查找的条件。如果在循环中需要异步的东西,那完全是另一个问题
router.post(“/”,异步(req,res)=>{
试一试{
如果(!checkIfOrderValid(请求正文)){
返回res.sendStatus(400);
}
let order=新订单(需求主体);
订单。_UserId='5b58836ed741e92d7416002e';
var show=wait show.findById(请求正文\u ShowId)
var take=req.body.ticketsPositions.find(元素=>{
return show.showTakenSeats.hasOwnProperty(元素[0]+“-”+元素[1])
});
如果(采取){
返回res.status(400).json({
“消息”:“座位已坐满”
})
}
var newOrder=await order.save().json()
res.send.json(newOrder);
}捕捉(错误){
资源状态(500)。发送(错误)
}
});另请注意:在.forEach()
中返回res.status(…).json(…)`是一个问题。它并没有停止您的.forEach()
循环,您可能试图发送多个响应,因此部分设计有点混乱。您可以通过链接承诺(无需嵌套)或使用async/await来实现您的目标。如果你想做一点研究的话,这两方面都有成千上万的文章。
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);
}
});