deferred.resolve() 没有迭代 for 循环中的最后一个元素

deferred.resolve() is not iterating the last element inside a forloop

在 model.findone 中,我得到一个包含 3 个元素的数组。在其他部分,我循环遍历每个项目并获取该特定项目的提供负责人。

但我只能获得 2 个产品 heads.Not 能够获取最后一个产品头。 我的代码有问题吗??

function getOfferingsHeads(id) {
    var deferred = Q.defer();
    var offeringHeads = [];
    model
    .findOne({ _id: id })
    .exec(function (err, item) {
        if(err) {
            console.log(err);
            deferred.reject(err);
        }
        else {
            // deferred.resolve(item.offerings);
            // var offeringsList = [];
            // offeringsList = item.offerings;

            for (var i = 0; i < item.offerings.length; i++) {
                executivesModel
                .findOne({offName: item.offerings[i] })
                .exec(function(err1, item1) {
                    if(err1){
                        console.log(err1);
                        deferred.reject(err1);
                    }
                    else{
                        offeringHeads.push(item1.offHead);
                        deferred.resolve(offeringHeads);
                    }
                });
            }
        }
    });
    return deferred.promise;
}

您不能多次解决 deferred,通常您根本不应该使用 deferred。由于 mongoose 有一个 promise-friendly API,你应该使用它。它会让你的代码更简洁:

function getOfferingHead(offName) {
    return executivesModel
        .findOne({offName: offName })
        .exec()
        .then(function (item) {
            return item.offHead;
        });
}

function getOfferingsHeads(id) {
    return model
        .findOne({ _id: id })
        .exec()
        .then(function (item) {
            return Q.all(item.offerings.map(getOfferingHead));
        });
}

要使用函数:

getOfferingsHeads('myId').then(function (heads) {
    console.log(heads);
});

不确定这是否是您的意图,但您不止一次地解决同一个承诺。

最新版本的 mongoose 允许您设置要使用的 Promise 库。

这里是对我认为你想要做的事情的更正:

//Somewhere near mongoose definition
mongoose.Promise = require('q').Promise;

function getOfferingsHeads(id) {
 var offeringHeads = [];
 return model
 .findOne({ _id: id })
 .then(function (item) {
    if(!item) {
     //Handle no results
     return Q.reject()
    }
    else {
        return Q.all(item.offerings.map(function(offering){
         executivesModel
            .findOne({offName: offering.name})
        }));
    }
 });
}

//Now you can use
getOfferingsHeads('someId').then(function (offerings) {
 ...
});