[英]Returning result from the backend to frontend in react/nodejs
-預留航班是該方案中的一個數組,其中存儲了用戶預留的航班。
[
{
_id: new ObjectId("61a4fa41fa24c144efce8038"),
FlightNumber: '1',
DepartureTime: 2013-08-03T02:00:00.000Z,
To: 'Cairo',
From: 'Alexandria',
ArrivalTime: 2014-08-03T02:00:00.000Z,
First: 1,
EconomySeats: 2,
BusinessSeats: 3,
ArrivalTerminal: ' ',
DepartureTerminal: ' ',
AvailableFSeats: [ 1 ],
AvailableESeats: [ 1, 2 ],
AvailableBSeats: [ 1, 2, 3 ],
createdAt: 2021-11-28T22:26:27.339Z,
updatedAt: 2021-11-29T22:09:13.946Z,
__v: 0,
BaggageAllowance: '6 kg',
TicketPrice: 5555,
Type: 'Normal'
},
{
_id: new ObjectId("61a51f3dcf237cbdc514698a"),
FlightNumber: '2',
DepartureTime: 2013-08-03T02:00:00.000Z,
To: 'Egypt',
From: 'Saudi Arabia',
ArrivalTime: 2014-08-03T02:00:00.000Z,
First: 4,
EconomySeats: 3,
BusinessSeats: 3,
ArrivalTerminal: 'Jaddah Airport',
DepartureTerminal: 'Cairo Airport',
AvailableFSeats: [ 1, 2, 3, 4 ],
AvailableESeats: [ 1, 2, 3 ],
AvailableBSeats: [ 1, 2, 3 ],
BaggageAllowance: '50 KG',
Type: 'Normal',
TicketPrice: 10000,
createdAt: 2021-11-29T18:43:09.158Z,
updatedAt: 2021-11-29T22:08:35.212Z,
__v: 0
}
]
- 這是我接觸到的代碼:
UserRoutes.get('/Showresflights', (req,res) => {
var rf = [];
var flights = [];
User.findById("61a52b332239b52f7ef5cc68", function (err, docs) {
rf = docs.ReservedFlights;
for(var i=0;i<rf.length;i++)
{
Flight.findById(rf[i]).then(result => {
//console.log(result);
flights[i]=result;
})
.catch(err => {
console.log(err);
});
}
console.log("flights:" + flights);
res.send(flights);
});
});
//每個航班都單獨在 object 中返回,而不是在所需的對象數組中。
{
_id: new ObjectId("61a4fa41fa24c144efce8038"),
FlightNumber: '1',
DepartureTime: 2013-08-03T02:00:00.000Z,
To: 'Cairo',
From: 'Alexandria',
ArrivalTime: 2014-08-03T02:00:00.000Z,
First: 1,
EconomySeats: 2,
BusinessSeats: 3,
ArrivalTerminal: ' ',
DepartureTerminal: ' ',
AvailableFSeats: [ 1 ],
AvailableESeats: [ 1, 2 ],
AvailableBSeats: [ 1, 2, 3 ],
createdAt: 2021-11-28T22:26:27.339Z,
updatedAt: 2021-11-29T22:09:13.946Z,
__v: 0,
BaggageAllowance: '6 kg',
TicketPrice: 5555,
Type: 'Normal'
}
{
_id: new ObjectId("61a51f3dcf237cbdc514698a"),
FlightNumber: '2',
DepartureTime: 2013-08-03T02:00:00.000Z,
To: 'Egypt',
From: 'Saudi Arabia',
ArrivalTime: 2014-08-03T02:00:00.000Z,
First: 4,
EconomySeats: 3,
BusinessSeats: 3,
ArrivalTerminal: 'Jaddah Airport',
DepartureTerminal: 'Cairo Airport',
AvailableFSeats: [ 1, 2, 3, 4 ],
AvailableESeats: [ 1, 2, 3 ],
AvailableBSeats: [ 1, 2, 3 ],
BaggageAllowance: '50 KG',
Type: 'Normal',
TicketPrice: 10000,
createdAt: 2021-11-29T18:43:09.158Z,
updatedAt: 2021-11-29T22:08:35.212Z,
__v: 0
}
-我考慮過保存從結果返回的每個 object,但我不知道這樣做的確切語法是什么,因為我什至不知道結果的類型是什么。
超級經典的問題“ 如何從異步調用返回響應? ”
Mongoose 方法是異步的,您可以await
它們。 還添加.lean()
以返回簡單的 JSON(更快)和.exec()
以返回您可以等待的真正 Promise。
UserRoutes.get('/Showresflights', async (req, res) => {
let flights = [];
try {
const rfs = (await User.findById("61a52b332239b52f7ef5cc68")).ReservedFlights;
for (let rf of rfs) flights.push(await Flight.findById(rf).lean().exec());
console.log("flights:" + flights);
res.json(flights);
} catch (err) {
console.log(err);
res.status(500).json(err); // Reply to your client in case of error, otherwise it's just gonna hang forever
}
});
但是,問題在於,您每次飛行都要進行一次數據庫調用。 您可以一次撥打所有航班的電話:
UserRoutes.get('/Showresflights', async (req, res) => {
try {
const rfs = (await User.findById("61a52b332239b52f7ef5cc68").lean().exec()).ReservedFlights;
const flights = await Flight.find({
_id: { $in: rfs }
}).lean().exec();
console.log("flights:" + flights);
res.json(flights);
} catch (err) {
console.log(err);
res.status(500).json(err);
}
});
一個更好的解決方案是讓您的航班直接由您的架構中的 Mongoose填充。 一個單一的數據庫調用整個:
const user = await User.findById("61a52b332239b52f7ef5cc68")
.populate("ReservedFlights")
.select("ReservedFlights") // optional, but you just select the field you're interested in
.lean()
.exec();
res.json(user.ReservedFlights); // bam
你的.then()
塊中的代碼是asynchronious
執行的,所以for
循環將在所有Flight.findById(rf[i])
調用完成之前完成。
你需要正確地等待所有的東西。
這是一個示例,它並行執行所有內容並最終使用Array.map()
和Promise.all()
等待示例:
UserRoutes.get('/Showresflights', (req, res) => {
// added async keyword to callback function so we can use "await" within callback
User.findById("61a52b332239b52f7ef5cc68", async function (err, docs) {
// correctly handle error event!
if(err) {
console.error(err)
res.status(500).send('Server error')
return
}
// use try catch for error handling instead of .catch()
try {
// I call Array.from() since I am not sure if docs.ReservedFlights is a real array!.
// you can probably omit the Array.from()..
const rf = Array.from(docs.ReservedFlights).map(flightId => {
// call the async function and return it's promise
return Flight.findById(flightId)
})
// now await all the Promises since they are async operations.
const flights = await Promise.all(rf)
// after the for loop is done, send back result.
console.log("flights:" + flights);
res.status(200).send(flights);
} catch (err) {
// on any error, send back a response!
console.log(err);
res.status(500).send('Server error.')
}
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.