我正在使用Express路由,因此我不确定为什么在这些数据库调用结束时我的“ purchasedCards”数组为空。我首先从几个数据库查询中收集了我需要的所有信息,然后将其放入上下文中以发送到前端。所有的数据库调用都工作正常……甚至是cardUpdator对象。我唯一的问题是将对象推入数组...
我对使用postgres数据库/ SQL是陌生的。任何建议都值得赞赏。
//User Account
router.get('/account', isLoggedIn, (req, res) => {
//Get User Info - First get the user info
db.query(`SELECT * FROM users WHERE userid = '${res.locals.user.id}';`)
.then(user => {
//Get user Purchases
db.query(`SELECT * FROM purchases WHERE newowner = '${res.locals.user.id}';`)
.then(purchases => {
let purchasedCards = []
//Get Card Info for Each Purchase
purchases.forEach( purchasedCard => {
//Get the card from user_cards table for standard card info.
db.query(`SELECT * FROM user_cards WHERE id = '${purchasedCard.card}';`)
.then( card => {
//Get Old Owner Info
db.query(`SELECT * FROM users WHERE userid = '${purchasedCard.oldowner}';`)
.then(oldOwner => {
let cardUpdator = {
cardName: card[0].name,
cardGame: card[0].game,
cardOldOwner: oldOwner[0].screen_name,
cardPID: purchasedCard.purchaseid,
cardTotal: purchasedCard.total,
cardId: purchasedCard.card,
}
purchasedCards.push(cardUpdator)
})
})
})
let context = {
name: user[0].screen_name,
email: user[0].email,
purchases: purchasedCards,
}
res.render('MyAccount.hbs', context)
})
})
})
答案 0 :(得分:0)
您应该等待异步操作完成使用Promise。为了使代码更简洁,请使用async await。
//User Account
router.get('/account', isLoggedIn, (req, res) => {
//Get User Info - First get the user info
db.query(`SELECT * FROM users WHERE userid = '${res.locals.user.id}';`)
.then(user => {
//Get user Purchases
db.query(`SELECT * FROM purchases WHERE newowner = '${res.locals.user.id}';`)
.then(purchases => {
//Get Card Info for Each Purchase
let getCardPromises = purchases.map(purchasedCard => {
//Get the card from user_cards table for standard card info.
return db.query(`SELECT * FROM user_cards WHERE id = '${purchasedCard.card}';`)
.then( card => {
//Get Old Owner Info
return db.query(`SELECT * FROM users WHERE userid = '${purchasedCard.oldowner}';`)
.then(oldOwner => {
let cardUpdator = {
cardName: card[0].name,
cardGame: card[0].game,
cardOldOwner: oldOwner[0].screen_name,
cardPID: purchasedCard.purchaseid,
cardTotal: purchasedCard.total,
cardId: purchasedCard.card,
}
return cardUpdator;
})
})
})
Promise.all(getCardPromises).then(getOwnerPromises => {
Promise.all(getOwnerPromises).then(purchasedCards => {
let context = {
name: user[0].screen_name,
email: user[0].email,
purchases: purchasedCards,
}
res.render('MyAccount.hbs', context)
})
})
})
})
})
编辑,我添加了async / await版本,绝对使代码更简洁
//User Account
router.get('/account', isLoggedIn, async (req, res) => {
//Get User Info - First get the user info
let user = await db.query(`SELECT * FROM users WHERE userid = '${res.locals.user.id}';`)
let purchases = await db.query(`SELECT * FROM purchases WHERE newowner = '${res.locals.user.id}';`)
//Get Card Info for Each Purchase
let purchasedCardsPromises = purchases.map(async (purchasedCard) => {
//Get the card from user_cards table for standard card info.
let [card, oldOwner] = await Promise.all([ db.query(`SELECT * FROM user_cards WHERE id = '${purchasedCard.card}';`),
db.query(`SELECT * FROM users WHERE userid = '${purchasedCard.oldowner}';`)])
let cardUpdator = {
cardName: card[0].name,
cardGame: card[0].game,
cardOldOwner: oldOwner[0].screen_name,
cardPID: purchasedCard.purchaseid,
cardTotal: purchasedCard.total,
cardId: purchasedCard.card,
}
return cardUpdator;
})
let purchasedCards = await Promise.all(purchasedCardsPromises)
let context = {
name: user[0].screen_name,
email: user[0].email,
purchases: purchasedCards,
}
res.render('MyAccount.hbs', context)
})
答案 1 :(得分:0)
最好使用async / await来避免多个回调。但是,出现意外行为的原因是因为您试图在已购买的Cards之前进行访问。这是因为JavaScript在本机中是异步的,因此在您访问PurchaseCards时,诺言尚未解决。
我有一个建议,如果您选择的话可以遵循,我使用了async / await。希望它会有所帮助。
async function getPurchasedCards(purchases) {
const purchasedCards = [];
return purchases.forEach((purchasedCard) => {
//Get the card from user_cards table for standard card info.
db.query(
`SELECT * FROM user_cards WHERE id = '${purchasedCard.card}';`,
).then((card) => {
//Get Old Owner Info
db.query(
`SELECT * FROM users WHERE userid = '${purchasedCard.oldowner}';`,
).then((oldOwner) => {
let cardUpdator = {
cardName: card[0].name,
cardGame: card[0].game,
cardOldOwner: oldOwner[0].screen_name,
cardPID: purchasedCard.purchaseid,
cardTotal: purchasedCard.total,
cardId: purchasedCard.card,
};
purchasedCards.push(cardUpdator);
if (purchasedCards.length === purchases.length) return purchasedCards;
});
});
});
}
async function getPurchasedCards(purchases) {
const purchasedCards = [];
return purchases.forEach((purchasedCard) => {
//Get the card from user_cards table for standard card info.
db.query(
`SELECT * FROM user_cards WHERE id = '${purchasedCard.card}';`,
).then((card) => {
//Get Old Owner Info
db.query(
`SELECT * FROM users WHERE userid = '${purchasedCard.oldowner}';`,
).then((oldOwner) => {
let cardUpdator = {
cardName: card[0].name,
cardGame: card[0].game,
cardOldOwner: oldOwner[0].screen_name,
cardPID: purchasedCard.purchaseid,
cardTotal: purchasedCard.total,
cardId: purchasedCard.card,
};
purchasedCards.push(cardUpdator);
if (purchasedCards.length === purchases.length) return purchasedCards;
});
});
});
}