【问题标题】:Assign multiple $http return data to an array in the called order将多个 $http 返回数据按调用顺序分配给数组
【发布时间】:2014-06-09 04:20:46
【问题描述】:
$scope.iter = 0;                         
$scope.myArray.forEach(function () {   
  $http.get($scope.myArray[$scope.iter].URL)
   .success(function (data) {
    $scope.myArray2.push(data);
    //$scope.myArray2[$scope.iter]=data
    });
$scope.iter++;
})           

上面的代码有效,但我希望 myArray2 中的结果与调用的顺序相同。我知道我不能指望 $scope.myArray2[$scope.iter]=data 工作,但这就是我需要的。

我查看了有关 Promise 的 Angular 文档,但无法弄清楚如何将其用于上述内容。

【问题讨论】:

    标签: arrays json angularjs http


    【解决方案1】:

    您可以将 get 请求中的所有承诺放在一个数组中,并使用 $q.all() 创建一个承诺,该承诺会在所有底层承诺解决时解决。然后,您可以按照添加到 requests 数组的顺序对响应进行迭代,并将每个响应的数据按顺序推送到数组中...

    function controller ($scope, $q) {
    
        // ...
    
        var requests = [];      
        var $scope.myArray2 = [];
        angular.forEach($scope.myArray, function (value) {   
            requests.push($http.get(value.URL));
        });
    
        $q.all(requests).then(function(results) {
            angular.forEach(results, function(result) {
                $scope.myArray2.push(result.data);
            });
        });
    }
    

    【讨论】:

    • 我是否必须等待所有底层承诺解决?在解决问题时,如何将每个分配到 myArray2 中的正确位置?
    • 您无需等待。结果数组将包含...嗯...“结果”(ajax 响应有效负载)按照将承诺添加到requests 数组的顺序。这是工作小提琴,安东尼打败了我;)。 fiddle.jshell.net/3C8R3/3
    • 还有随机延迟响应的小提琴,以证明 promise 确实保留了它们的顺序 --> fiddle.jshell.net/3C8R3/4
    • $q.all() 直到所有底层承诺都解决后才会解决,所以是的,使用这种方法,您必须等待所有承诺都解决,然后才能迭代结果。要在他们得到解决时这样做,您必须考虑其他事情。
    【解决方案2】:

    不明白你想要实现什么,但这里有一个控制器中简单的延迟承诺的例子:

    var firstDefer= $q.defer();
    
    firstDefer.promise.then(function(thing){
        // here you make the first request,
        // only when the first request is completed
        //the variable that you return will be filled and
        //returned. The thing that you return in the first .then
       // is the parameter that you receive in the second .then
        return thingPlusRequestData;
    }).then(function(thingPlusRequestData){
        //second request
    
        return thingPlusPlusRequestData;
    }).then(function(thingPlusPlusRequestData){
        //and so on...
    });
    
    firstDefer.resolve(thing);
        //when you call .resolve it tries to "accomplish" the first promise
      //you can pass something if you want as a parameter and it will be
     // the first .then parameter.
    

    希望这对你有帮助:D

    【讨论】:

      【解决方案3】:

      您通常不会按照调用$http.get(...) 函数的顺序获得结果。请注意success(...) 函数是异步调用的,只要 http 响应进来,这些响应的顺序是完全不可预测的。

      但是,您可以通过等待所有响应完成来解决此问题,然后根据您的标准对其进行排序。

      这是工作小提琴:http://fiddle.jshell.net/3C8R3/3/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多