将 q.all 正确放置在 array.map 中使用 _.forEach



我有以下代码,它使用find()使用array.map提取的值搜索我的mongodb。所述搜索返回一个对象,然后我使用该_.forEach提取值。

以这篇文章为基础,但是他的例子和我的例子之间的区别在于他只使用了一个循环。我用两个。在这种情况下,我应该把q.all()放在哪里?

这是我的代码。请注意,这是服务器端的:

'use strict';
var q = require('q');
exports.downloadEmployee = function (req, res) {
    var tempCtr = [];
    if (req.params.hasdr === "yes") {
        return queries.generateDirectReportsCSV(req.params.id).then(function (directReports) {
            return directReports;
        }).then(function (directReports) {
            var empIDcoll = _.pluck(directReports.Data, "employeenumber");
            return empIDcoll;
        }).then(function (empIDcoll) {
            var promises = [];
            empIDcoll.map(function (id) {
                return EmployeeInfo.find({ employeeID: id }, function (err, results) {
                    if (err) { return err; }
                    _.forEach(results, function (item) {
                        if (item) {
                            tempCtr.push({
                                employeeID: item.employeeID,
                                employeeName: item.employeeName
                            });
                            promises.push(tempCtr);
                        }
                    });
                });
                q.all(promises).then(function (results) {
                    return res.json(results);
                });
            });
        });
    }

当我运行这个时,我没有得到任何结果。

任何答案将不胜感激。

谢谢。

更新:我决定修改我的代码,并用通常的for loop替换array.map

.then(function (empIDcoll) {
    for (var i = 0; i <= empIDcoll.length - 1; i++) {
        var promise = EmployeeInfo.find({ employeeID: empIDcoll[i] }, function (err, results) {
            if (err) { return err; }
            _.forEach(results, function (item) {
                if (item) {
                    tempCtr.push({
                        employeeID: item.employeeID,
                        employeeName: item.employeeName,
                        currentShift: item.currentShift,
                        isOpenToIntlAssignment: item.isOpenToIntlAssignment,
                        desiredRole1: item.desiredRole1,
                        desiredRole2: item.desiredRole2,
                        desiredRole3: item.desiredRole3,
                        desiredRoleOther: item.desiredRoleOther,
                        passportInfo: item.passportInfo,
                        visaInfo: item.visaInfo,
                        yrsInIT: item.yrsInIT,
                        yrsAsCustomerPM: item.yrsAsCustomerPM,
                        yrsAsCustomerProgM: item.yrsAsCustomerProgM,
                        primaryDomain: item.primaryDomain,
                        primaryDomainOther: item.primaryDomainOther,
                        primaryIndustry: item.primaryIndustry,
                        primaryIndustryOther: item.primaryIndustryOther,
                        isPMPCertified: item.isPMPCertified,
                        pmpCertExpiryDate: item.pmpCertExpiryDate,
                        isPGMPCertified: item.isPGMPCertified,
                        pgmpCertExpiryDate: item.pgmpCertExpiryDate,
                        isScrumCertified: item.isScrumCertified,
                        scrumCertExpiryDate: item.scrumCertExpiryDate,
                        biggestProjectTCV: item.biggestProjectTCV,
                        biggestTeamSizeManaged: item.biggestTeamSizeManaged,
                        avgTeamSizeManaged: item.avgTeamSizeManaged,
                        biggestBilledFTE: item.biggestBilledFTE,
                        avgBilledFTE: item.avgBilledFTE
                    });
                }
            });
        });
        promises.push(promise);
    }
    return q.all(promises).then(function(data){
        return res.json(data);
    });
});

。但它仍然没有返回任何东西。我做错了什么?

第一次几乎是正确的!

当你这样做时:

var promises = [];
empIDcoll.map(function (id) {
    return EmployeeInfo.find({ employeeID: id }, function (err, results) {
        if (err) { return err; }
        _.forEach(results, function (item) {
            if (item) {
                tempCtr.push({
                    employeeID: item.employeeID,
                    employeeName: item.employeeName
                });
                promises.push(tempCtr);
            }
        });
    });
    q.all(promises).then(function (results) {
        return res.json(results);
    });
});

你的q.all位置错误(在.map内(;你把对象推到你的promises数组里,而不是实际的承诺。尝试执行以下操作:

// Here, we will build an array of promises by transforming each element of `empIDcoll` to a promise (via `.map`).
var promises = empIDcoll.map(function (id) {
    return EmployeeInfo.find({ employeeID: id }).exec(); // I assume that .exec() will return a promise.
});
q.all(promises).then(function (results) { // `results` will be an array, each element will contain the result of each promise pushed to `promises`.
    return res.json(results);
});

试试这个。这可能需要一些调整(让我们知道(,因为我真的不知道您的应用程序/模型的结构。

删除 EmployeeInfo.find 之前的 return 语句?

看看,

var promises = questions.map(function(question) {
        return $http({
            url   : 'upload/question',
            method: 'POST',
            data  : question
        });
    });
    return $q.all(promises);

我的第一个建议是首先停止循环访问 employeeId。你可以像这样使用 mongoDB 的 $in 运算符

EmployeeInfo.find({ employeeID: {$in: empIDcoll} }, function (err, results) {
     if(err) {
       //handle error
       return err;
     }
     res.json(results);
});

但是由于我不知道您的应用程序,我真的无法判断您是否想遍历empIdColl。


循环遍历 empIdColl

现在我不确定您的monogdb查询是否会返回promise,以便更安全,我会假设它不会

var promises = empIDcoll.map(function (id) {
    var singleDefer = q.defer(); //create a deferred object which has promise in it
    EmployeeInfo.find({ employeeID: id }, function(err, results) {
         if(err) {
             return singleDefer.reject(err);
         }
         return singleDefer.resolve(results); //resolve whole array
    });
    return singleDefer.promise;
});
q.all(promises)
.then(function (arrayOfResults) {
    var responseData = [];
    arrayOfResuls.forEach(function(results) {
          results.forEach(function(individualResult) {
              if(individualResult) {
                   responseData.push({
                       employeeID: item.employeeID,
                       ...
                       ...
                       avgBilledFTE: item.avgBilledFTE
                   });
              }
          });
    });
    return res.json(responseData);
})
.catch(function(err) {
    //handle error
});

我在这里发布我的工作解决方案,以造福那些将来可能遇到相同问题的人。感谢SinDeus提供简单简洁的解决方案。:)

.then(function (empIDcoll) {
        // push user's employee number in first row
        empIDcoll.unshift(req.params.id);
        // return resolved promises from EmployeeInfo.find()
        // this will return user's direct reports' information (if any)
        var promises = empIDcoll.map(function (id) {
            return EmployeeInfo.find({ employeeID: id }).exec();
        });
        // Take resolved promises from above statement and iterate to get final results.
        q.all(promises).then(function (results) {
            _.forEach(results, function (item) {
                var len = item.length - 1;
                if (len >= 0) {
                    tempCtr.push({
                        employeeID: item[0].employeeID,
                        employeeName: item[0].employeeName
                        // ... other fields here ...
                    });
                }
            });
            return res.json(tempCtr);
        });
    });
}

最新更新