在AngularJS中按顺序运行$ http请求

时间:2014-10-17 13:26:57

标签: javascript angularjs

我的$scope上有一系列项目。对于每个项目,我需要运行三个$ http请求。无论是否存在失败,这些请求必须按特定顺序运行。我不确定如何优雅地做到这一点,有了承诺的范例。我有很多重复的代码,看起来真的很混乱。我必须做错了。目前,我有以下内容:

$scope.items = getItems();
$scope.currentIndex = 0;

$scope.executeItem = function() {
  $http.get($scope.items[$scope.currentIndex].urlA).then(
    function (resA) {
      $scope.items[$scope.currentIndex].urlAWorks = true;
      $http.get($scope.items[$scope.currentIndex].urlB).then(
        function (resB) {
          $scope.items[$scope.currentIndex].urlBWorks = true;

          $http.get($scope.items[$scope.currentIndex].urlC).then(
            function (resC) {
              $scope.items[$scope.currentIndex].urlCWorks = true;
              $scope.currentIndex = $scope.currentIndex + 1;
              $scope.executeItem();
            },

            function (errC) {
              $scope.items[$scope.currentIndex].urlCWorks = false;
              $scope.currentIndex = $scope.currentIndex + 1;
              $scope.executeItem();
            }
          )
        },
        function (errB) {
          $scope.items[$scope.currentIndex].urlBWorks = false;
        }
      );
    },

    function (errA) {
      $scope.items[$scope.currentIndex].urlAWorks = false;
      $http.get($scope.items[$scope.currentIndex].urlB).then(
        function (resB) {
          $scope.items[$scope.currentIndex].urlBWorks = true;

          $http.get($scope.items[$scope.currentIndex].urlC).then(
            function (resC) {
              $scope.items[$scope.currentIndex].urlCWorks = true;
              $scope.currentIndex = $scope.currentIndex + 1;
              $scope.executeItem();
            },

            function (errC) {
              $scope.items[$scope.currentIndex].urlCWorks = false;
              $scope.currentIndex = $scope.currentIndex + 1;
              $scope.executeItem();
            }
          )
        },
        function (errB) {
          $scope.items[$scope.currentIndex].urlBWorks = false;
        }
      );
    }
  );
};

我是否真的正确地链接了承诺?这看起来很糟糕。

谢谢

2 个答案:

答案 0 :(得分:3)

你没有使用承诺:)因为.then会返回一个承诺,你可以这样做:

$http.get(urlA)
  .then(function(dataA){
    DoStuffWithA(dataA);

    return $http.get(urlB);
  })
  .then(function(dataB){
    DoStuffWithB(dataB);

    return $http.get(urlC);
  })
  .then(function(dataC){
    DoStuffWithC(dataC);

    return true;
  })

答案 1 :(得分:1)

使用参数绑定创建对这些函数的引用。而不是

      $http.get($scope.items[$scope.currentIndex].urlC).then(
        function (resC) {
          $scope.items[$scope.currentIndex].urlCWorks = true;
          $scope.currentIndex = $scope.currentIndex + 1;
          $scope.executeItem();
        },

        function (errC) {
          $scope.items[$scope.currentIndex].urlCWorks = false;
          $scope.currentIndex = $scope.currentIndex + 1;
          $scope.executeItem();
        }
      )

执行:

var next_thingy = function (worked) {
  return function () {
    $scope.items[$scope.currentIndex].urlCWorks = worked;
    $scope.currentIndex = $scope.currentIndex + 1;
    $scope.executeItem();
   }
}

$http.get($scope.items[$scope.currentIndex].urlC)
  .then(next_thingy(true),next_thingy(false));

然后把它们连在一起:

var req1 = $http.get(...)
var thingies = {}

var thingies.next_thingy = function( worked) {
  return function() {
    var req = $http.get(...)
    ...
    req.then(thingies.next_thingy2(true),thingies.next_thingy2(false))
  }
}
req1.then(thingies.next_thingy(false),thingies.next_thingy(true))
var thingies.next_thingy2 = function(worked2) {
  return function() {
    var req2 = $http.get(...)
    ...
    req2.then(thingies.next_thingy3(true),thingies.next_thingy3(false); 
  }
}
var thingies.next_thingy3 = function(worked3) {
  return function() {
    ...
  }
}

你可以将它们全部平行分叉,然后等待它们完成:

var third_reqs = []
$scope.items.forEach(function(item) {
   var third_req_defer = $q.defer()
   third_reqs.push(third_req_defer.promise)
   ...
    var thingies.next_thingy3 = function(worked3) {
      return function() {
       ...
       third_req_defer.resolve()
      }
   }
}) 
$q.all(third_reqs).then(
    function() { $log.log("Finished!")}, 
    function(){ $log.error("some third reqs failed.")})