我最近开始使用 Mongoose 和 Node.js,在处理异步 Mongoose 查询的结果时遇到一些困难。我有一个名为“组”的集合,并且组可以包含位于名为“成员”的单独集合中的成员。为了实现这一点,每个组都有一个名为“members”的字段,它是一个 ObjectId 数组。此外,每个成员都有一个由 ObjectId 引用的配置文件。因此,每个成员都有一个名为“个人资料”的字段,并且个人资料存储在名为“个人资料”的集合中。
现在我想获取给定组中的配置文件列表。因此我写了这段代码:
// Function that returns a profile by a given objectId
function getprofile(profileId, profile) {
Profile
.findById(profileId)
.exec(function(err, res) {
if(err) { return null; }
if(!res) { return null; }
return res;
});
}
// Main function that returns a list of all (unique) profiles from members within a group
Group
.findById(req.params.id)
.populate('members')
.exec(function(err, group) {
if(err) { return handleError(res, err); }
var tmpProfiles = [];
var allProfiles = [];
for(var i=0; i<group.members.length; i++) {
var memberProfile = group.members[i].profile;
// Check if the member's profile is already in the array
if(objectIndexOf(tmpProfiles, memberProfile) == -1) {
tmpProfiles.push(memberProfile);
allProfiles.push(getprofile(memberProfile)); // add the profile to the array of profiles
}
}
return res.json(allProfiles); // this returns an empty array
});
问题在于“Profile.findById”函数和“Group.findById”函数都是异步的,因此该函数返回一个仅包含“null”值的数组。我知道我可以通过使用“异步”库来解决这个问题,但这对我来说不是一个选择,所以我必须经历“回调 hell ”。有人可以通过解决这个问题让我走上正确的方向吗?我已经找到了一些使用函数递归调用的解决方案,但我不知道在这种情况下如何实现它。
最佳答案
您可以利用 mongoose 方法返回 Promise 的事实。
注意:您需要使用 Node >= v0.12 或在模块中拥有 Promise 库 require
d。
// Function that returns a profile by a given objectId
function getprofile(profileId, profile) {
return Profile.findById(profileId); // return the Promise of this `findById` call
}
// Main function that returns a list of all (unique) profiles from members within a group
Group
.findById(req.params.id)
.populate('members')
.then(function(group) {
var tmpProfiles = [];
var promises = []; // store all promises from `getprofile` calls
for(var i = 0; i < group.members.length; i++) {
var memberProfile = group.members[i].profile;
// Check if the member's profile is already in the array
if(objectIndexOf(tmpProfiles, memberProfile) == -1) {
tmpProfiles.push(memberProfile);
promises.push(getprofile(memberProfile));
}
}
return Promise.all(promises);
})
.then(function(allProfiles) {
res.json(allProfiles);
})
.catch(function(err) {
//todo: handle error
console.log(err);
});
关于javascript - 在 Node.js 中的异步函数中填充数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31390672/