以串行方式在 angular 中链接 http post 和 q 服务

chaining http post and q service in angular in serial fashion

我在 angular、

中有此代码
    $http({
        method:'POST',
        url :'someURL',    //returns an array of urls [url1, url2, url3..]
        data : dataObj

    })
    .then(function(response) {
        var items = response.data;
        var promises = [];
        $scope.output =[];
        items.forEach(function(el){
            return promises.push($http.get(el)); //fills the promise[] array
        });

    var ignore = function(x) { return x.catch(function(){}); } // To ignore if promise does not get resolved (only accept responses with status 200)
    var all = $q.all( promises.map(ignore) ); //chaining promises array 
    all.then(function success(d){
        console.log($scope.output);  //want the output to be ["text1", "text2", "text3"...]
    });

    for (var i=0; i < promises.length ; i++){

        promises[i].then(success).catch(function (){
        });
        function success(r){
            $scope.output.push(r.data.text);   //{text: "text1"}
        }
    }
    });

此操作的结果存储在$scope.output中。在执行时,我得到的输出为 ["text2", "text3", "text1" ...],这不是串行方式。我的问题是如何以串行方式执行此操作,以便输出为 ["text1", "text2", "text3" ...]

没有测试,但从第一眼来看我会说你需要把 for() 循环放在 all.then().

all.then(function success(d){
  console.log($scope.output);

  for (var i=0; i < promises.length ; i++) {
    promises[i].then(success).catch(function () { });

    function success (r) {
      $scope.output.push(r.data.text);
    }
  }
});

因为否则你会遍历部分未解决的承诺。那些较早解决的问题将在队列中跳过。

all.then() 中使用 for() 循环可以确保所有 promise 都已解析,并在使用 promises[i].then(success).[=14= 调用时将它们自己添加到输出列表中]

IMO,你不应该在 for 循环中使用回调。我认为,这是导致这种行为的原因。我希望它会起作用。无需添加最后一个 for 循环。

var all = $q.all( promises.map(ignore) );
all.then(function success(d){
    d.forEach(function(res){
         $scope.output.push(r.data.text);
    });
    console.log($scope.output);  
});

将最后一个 for 循环替换为以下内容:

angular.forEach(promises, function(promise, index){
       promise.then(success).catch(function (){});
       function success(r){
           $scope.output[index] = r.data.text;
       }
});

由于闭包范式,index 变量将在承诺解决时在 success 处理程序中可用,无论承诺以何种顺序解决,结果将被放置到 output 数组按照原来的顺序排列。