javascript - 在 Node.js 中的异步函数中填充数组

标签 javascript node.js mongodb asynchronous

我最近开始使用 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 库 required。

// 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/

相关文章:

javascript - 根据 highcharts 中的某些条件格式化样式

javascript - 绑定(bind) uncaughtException 事件来处理回调 NodeJS 中发生的错误是最佳实践吗?

algorithm - Memcache 驱逐监控系统

mongodb - 如何在 MongoDB $lookup 中使用变量

javascript - 当我不应该这样做时,我可以将图像拖放到其他图像上

javascript - 每次按 "next"按键后,自定义 js 图像查看器加载速度变慢

javascript - 在列上添加底行以求和整列的值

node.js - npm start 不起作用。我已经尝试了一切。我很困惑

javascript - 以编程方式获取已启动 Puppeteer 实例的命令行标志

javascript - 如何使用另一个数组更新 MongoDB 集合中的数组但仅更新更改的值?