一个承诺之后的承诺循环

时间:2014-10-21 20:40:33

标签: javascript angularjs promise nested-loops angular-promise

我只需写一个承诺,然后,凭借这个承诺的结果,一组电影,我必须在数组内循环,并为每个元素做一个远程调用(也有承诺)来装饰其他数据。 我试过这种方式:

var deferred = $q.defer();
var promises = [];

angular.forEach(tree, function(node) {
    promises.push(
        APICall.GetMovieList(node).then(function(success){
            var contents = {};
            //simple data manipulation
            return contents;
        })
        .then(function(contents){ /////////////////////// concatenation part that won't work
            angular.forEach(contents, function(content) {
                APICall.GetMovieDetails(content.ID).then(function(success){
                    content.metadata = success.metadata;    
                });
            });
            return contents;
        })
    );
});


$q.all(promises).then(ResolveFunction);

return deferred.promise;

为了便于阅读,我删除了ResolveFunction,它只是管理promise数组并执行$ q.resolve(结果)。 问题在于没有连接它就像魅力一样,但是通过必要的连接,它只返回与之前相同的结果,它的行为就像这样,因为异步调用将被调用... 在连接部分中创建另一个延迟并嵌套$ q.all并返回$ q.all解决的数组保证是一个好主意吗? 非常感谢

1 个答案:

答案 0 :(得分:1)

您无需创建第二个deferred(根本不需要deferred。)
只需执行以下操作:

var promises = [];

angular.forEach(tree, function(node) {
    promises.push(
        APICall.GetMovieList(node).then(function(success){
            var contents = {};
            //simple data manipulation
            return contents;
        })
        .then(function(contents){ 
            var contentPromises = [];
            angular.forEach(contents, function(content) {
                contentPromises.push(
                    APICall.GetMovieDetails(content.ID).then(function(success){
                        content.metadata = success.metadata;    
                    })
                );
            });
            return $q.all(contentPromises).then(function() {
                return contents;
            });
        })
    );
});

return $q.all(promises).then(function(nodes) {
    return nodes;
});

这是一个有效的 jsfiddle-demo ,其中有一个模拟APICall - 工厂。