【问题标题】:chaining http post and q service in angular in serial fashion以串行方式以角度链接 http post 和 q 服务
【发布时间】:2016-09-05 09:23:37
【问题描述】:

我有这个角度的代码,

    $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" ...]

【问题讨论】:

    标签: angularjs promise q


    【解决方案1】:

    用以下代码替换你最后的 for 循环:

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

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

    【讨论】:

    • 是的,您应该使用闭包来捕获每次迭代的索引。我更正了答案。
    【解决方案2】:

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

    【讨论】:

    • 感谢您的输入,我尝试了完全相同的事情,但我仍然得到了无序而不是顺序的结果:(
    【解决方案3】:

    没有测试它,但从第一个角度来看,我会说你需要将 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) 调用它们时会将它们自己添加到输出列表中。

    【讨论】:

    • 我尝试了您的解决方案,但结果仍然不正常:(
    猜你喜欢
    • 2013-05-02
    • 1970-01-01
    • 2022-01-08
    • 2013-12-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多