Javascript Angular:如何链接未知数量的承诺

cas*_*man 7 javascript asynchronous promise

我正在写一个Angular.js服务来提取一些JSONFeed.最初,该服务不知道要请求的资源数量/数量; 它们依赖于另一个请求返回的ID.

我很头疼将$http服务请求链接在一起.有没有常用的模式来做到这一点?

我已尝试Array.reduce在另一个线程上建议的技术,但在同步ID和请求的数据时遇到问题.

这就是我到目前为止所拥有的.有没有人有什么建议?

aService.factory('dummy', function($http){
    // Dummy resources.
    var resources = [   
      'http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js',
      'http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js',
      'http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js'
    ];
    return {
        data: function(callback){

            var jquerySources = []

            var promiseChain = $http({method: 'GET', url: resources[0]});
            var l = resources.length
            for (var i = 1; i < l; i++ ){
                promiseChain.then(function(data){

                    jquerySources.push({
                        url: resources[i],
                        source: data
                    });

                    promise_chain = $http({method: 'GET', url: resources[i]});
                    if (i === l){
                        return callback(jquerySources);
                    }
               });
            }
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

谢谢.

Ole*_*Aza 6

如果您需要按顺序执行请求,则可以创建一个可以用作链头的承诺.然后,你可以将$ http调用链接到那个头并解决头部承诺:

aService.factory('seq', function($http, $q){
    // Dummy resources.
    var resources = [   
      'http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js',
      'http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js',
      'http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js'
    ];
    var deferred = $q.defer();
    var resourcePromise = deferred.promise;
    var res = [];
    angular.forEach(resources, function(resource){
      return resourcePromise.then(function(){
        return $http({ method: 'GET', url: resource });
      }).then(function(data){
        res.push({res: resource, data : data});
      });
    });

    deferred.resolve();

    return {
        getResource: resourcePromise.then(function(){
          return res;
        })
    };
});
Run Code Online (Sandbox Code Playgroud)

但如果请求是并行的 - 那么这将是更简单的解决方案.只是一系列的承诺,只需调用$ q.all函数等待解决所有的承诺.

aService.factory('par', function($http, $q){
    // Dummy resources.
    var resources = [   
      'http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js',
      'http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js',
      'http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js'
    ];
    var promises = [];
    var res = [];
    angular.forEach(resources, function(resource){
      promises.push(
        $http({ method: 'GET', url: resource }).then(
          function(data){
            res.push({res: resource, data : data});
          })
        );
    });

    return {
        getResource: $q.all(promises).then(function(){
          return res;
        })
    };
});
Run Code Online (Sandbox Code Playgroud)

另请注意,在这两种情况下,我们都有res数组来收集请求结果.

编辑: Plunker举例