deferred.resolve()不迭代forloop中的最后一个元素

时间:2016-07-17 20:38:04

标签: angularjs mongoose mean-stack q

在model.findone中我得到一个由3个元素组成的数组。在其他部分,我循环遍历每个项目&获取该特定项目的提供者。

但是我只能获得2个提供头。无法获取最后一个提供头。 我的代码有问题吗?

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;
}

2 个答案:

答案 0 :(得分:2)

您无法多次解决延迟,并且一般情况下您根本不应使用延迟。由于mongoose具有承诺友好的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);
});

答案 1 :(得分:0)

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

最新版本的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) {
 ...
});