我是 Mongo 和 Node 的新手。我目前正在使用 Mongoskin 和 Bluebird 来处理数据库连接和查询(如此处建议:https ://stackoverflow.com/a/23687958/2701348 )。
我有三个集合:用户、活页夹和卡片。
Binders 集合包含有关每个用户的卡片的信息。Binder 中的每个文档都具有以下属性:
User Id <--- that refers to the User owning the Card
Card Code <--- that refers to a Card
Count <--- that refers to the number of cards owned by the User
我更喜欢有一个单独的 Cards 集合,这样当 Card 更改时,它会为所有用户绑定器更改。
现在我愿意为给定的用户检索一个数组,例如:
[{card: {card document}, count: 4}, ...]
我有以下问题:
- 调用所有异步数据库回调后,应关闭数据库连接
- 卡片数组应该在最后一个db.collection ('cards').find返回结果之后返回
我知道我的以下代码是错误的,但可以作为讨论的起点:
var getAllBinderCards = function(req, res){
var db = req.db;
var userId = req.userId;
var promiseBinders = db.collection('binders').find({userId: userId}).toArrayAsync();
promiseBinders.then(function(binderCards) {
if (binderCards) {
var promiseCards;
//console.log("------ binderCards: ", binderCards);
var cards = [];
for (var i = 0; i < binderCards.length; i++) {
var binderCard = binderCards[i];
promiseCards = db.collection('cards').find({Code: binderCard.Code}).toArrayAsync();
promiseCards.then(function(cardsDB){
if(cardsDB){
//console.log("Cards found: ",binderCard.Code, cardsDB);
for (var i = 0; i < cardsDB.length; i++) {
cardsDB[i].count = binderCard.count;
};
cards.concat(cardsDB);
}
});
}
promiseCards.then(function(){
db.close();
console.log("Binder Cards: " , cards);
res.json(cards);
});
}
});
}
我正在努力弄清楚如何正确处理承诺的异步调用,以便发回整个数组并关闭数据库连接。
我想我应该尝试在 for 循环之前构建一个 Promise,并使用它来链接 Cards Promise 上的查询,最后链接 db.close() 和 res.json(cards) 语句。
[编辑] 也许最简单的解决方案是在单个db.collection('cards').find({Code: {$in: [bindersCodeArray] }}).toArrayAsync();中简单地使用 $in 过滤器。并避免 for 循环:
var getAllBinderCards = function(req, res){
var db = req.db;
var userId = req.userId;
var promiseBinders = db.collection('binders').find({userId: userId}).toArrayAsync();
promiseBinders.then(function(binderCards) {
if (binderCards) {
var binderCodes = binderCards.map(function(element){
return element.Code;
});
var promiseCards = db.collection('cards').find({Code: {$in: binderCodes} }).toArrayAsync();
promiseCards.then(function(cards){
var bindersDictionary = {};
for (var i = 0; i < binderCards.length; i++) {
bindersDictionary[binderCards[i].Code] = binderCards[i].count;
};
for (var i = 0; i < cards.length; i++) {
cards[i].count = bindersDictionary[cards[i].Code];
};
db.close();
console.log("Binder Cards: " , cards);
res.json(cards);
});
}
});
}
我仍然很好奇是否有一种优雅的方法可以使用 Promise 来解决这个谜题。