$ http回调的执行顺序

时间:2014-10-08 13:34:39

标签: angularjs http callback factory

工厂方法执行优先级似乎最高,因此回调没有数据可以处理。使这项工作的最佳方法是什么?

我有这种工厂

app.factory('jsonService', function($http) {
    return {
        getDistricts: function(callback) {
            $http.get('data/districts.json').success(callback);
        },
        getLocations: function(path,callback) {
            $http.get('data/'+path+'.json').success(callback);
        }
    };
});

和控制器

var app = angular.module('sandbox', []);
app.controller('sandboxCtrl',function ($scope,jsonService) {

 //This one works
    $scope.init1= function(){
        jsonService.getDistricts(function(data){
            $scope.districts = data;
            $scope.currentDistrict = $scope.districts[0].name;

             jsonService.getLocations($scope.currentDistrict,function(data){
            $scope.locations1 = data;

        })
        });

    };
    $scope.init1();

    //This one does not 
    $scope.init2= function(){
        jsonService.getDistricts(function(data){
            $scope.districts = data;
            $scope.currentDistrict = $scope.districts[0].name;
        })
        jsonService.getLocations($scope.currentDistrict,function(data){
            $scope.locations1 = data;
        });

    };
    $scope.init2();

});

这是有效的plunker

2 个答案:

答案 0 :(得分:1)

init1()是这样做的正确方法。 init2()确实有效,因为在jsonService.getLocations()完成之前会调用jsonService.getDistritcs()。角度$http服务是异步的。由于jsonService.getLocations()取决于jsonServicd.getDistricts()的数据,因此您必须等到.getDistricts()完成后才能调用.getLocations()。一种方法是在.getLocations()回调中调用.getDitricts(),就像在init1()中一样。

答案 1 :(得分:1)

Angular有一个名为$ q(documentation)的承诺的实现,您应该阅读。

由于http调用的异步性质,存在竞争条件。请查看下面链接的更新代码,其中显示了使用promises连续处理两个调用的代码运行(成功)的示例。

因此,在第一次通话成功后,由于承诺的力量,它将在不使用回调的情况下调用您的第二种服务方法。

jsonService.getDistricts()
  .success(function(data) {
    $scope.districts = data;
    $scope.currentDistrict = $scope.districts[0].name;
    jsonService.getLocations($scope.currentDistrict)
      .success(function(locationData) {
        $scope.locations = locationData;
      })
  });

updated PLKR

承诺澄清: 基本承诺的原始实现使用then来处理从$http返回的响应和承诺,添加将从响应对象中解压缩数据的其他方法(successerror)如果您只是使用then,则需要处理。