简体   繁体   English

使用AngularJS中的Promise进行$ http-calls的条件链接

[英]Conditional Chaining of $http-calls with Promises in AngularJS

I have to execute three different $http-calls sequentially which depend on each other. 我必须顺序执行三个不同的$ http-calls,它们相互依赖。 Until now my working solution ist something like this 到目前为止,我的工作解决方案是这样的

$http.get(".../1/...").success(function(){
    $http.get(".../2/...").success(function(){
        $http.get(".../3/...").success(function(){

        });
    });
});

Now there is a certain change to be made: The first call should be skipped if a condition is true. 现在有一些变化:如果条件为真,则应跳过第一个调用。 I could do it like this: 我可以这样做:

if(skipCallOne) {
    $http.get(".../2/...").success(function(){
        $http.get(".../3/...").success(function(){

        });
    });
} else {
    $http.get(".../1/...").success(function(){
        $http.get(".../2/...").success(function(){
            $http.get(".../3/...").success(function(){

            });
        });
    });
}

This obviously leads to massive code replication. 这显然会导致大量的代码复制。 I see that this could be reduced if i used propper functions for the particular $http-calls. 我看到如果我使用特定$ http-calls的propper函数,这可以减少。 But as I understand a better solution would be to use and chain the $http-promises properly, like this: 但据我所知,更好的解决方案是正确使用和链接$ http-promises,如下所示:

$http.get(".../1/...").then(function(){
    return $http.get(".../2/...");
}).then(function() {
    return $http.get(".../3/...");
}).then(function() {

});

But now my question is, how can I conditionaly skip the first call with the least code replication? 但现在我的问题是,我如何以最少的代码复制条件跳过第一次调用?

You can try this approach: 你可以尝试这种方法:

$q.when(skipCallOne || $http.get(".../1/..."))
  .then(function() {
    return $http.get(".../2/...");
  }).then(function() {
    return $http.get(".../3/...");
  }).then(function() {
});

You can wrap the $http.get calls in functions that test the condition and return the $http.get promise if the conditions apply or a pre-resolved promise if not. 您可以在测试条件的函数中包装$http.get调用,如果条件适用则返回$http.get promise,否则返回预解析的promise。

function callOne() {
    if(condition) {
        return $http.get(".../1/...");
    } else {
        var deferred = $q.defer();
        deferred.resolve();
        return deferred.promise;
    }
}

callOne().then(function() {
    return $http.get(".../2/...");
})

I like to be able to see stuff like this working, so I put this little controller together to demonstrate the promises resolving, with a conditional $http.get running first. 我希望能够看到这样的东西工作,所以我把这个小控制器放在一起演示了解决的promises,首先运行条件$ http.get。 I don't claim that this is elegant or as clever as the other answers, though I think it is quite similar to Cristian's solution. 我并不认为这比其他答案更优雅或更聪明,尽管我认为它与Cristian的解决方案非常相似。

Note: One thing that may make this difficult to understand is answers to this question often show chaining $http calls which are only executed , and for the sake of simplicity, the values those calls are returning are ignored and it may not be immediately clear how to break things apart to actually get at the values. 注意:有一点可能使这个难以理解的是这个问题的答案经常显示链接$ http调用只执行 ,并且为了简单起见,这些调用返回的值被忽略,可能不会立即清楚将事情分开以实际获得价值观。

Demo 演示

app.controller('MainCtrl', function($scope, $q, $http) {
  $scope.x = true;

  var firstHttp = function() {
    var deferred = $q.defer()
    if($scope.x) {
      data = 'x was true'
       deferred.resolve(data);
    } else {
      $http.get('test.json')
      .then(function(data) {
        $scope.data1 = data;
        deferred.resolve(data);
      })
    }  
    return deferred.promise
  }

  $scope.myGetterFn = function() {
    firstHttp()
    .then(function(data) 
    {
      data.data ? $scope.data1 = data : $scope.datax = data;
      $http.get('test2.json')
    .then(function(data2) 
    {
        $scope.data2 = data2
        $http.get('test3.json')
    .then(function(data3) 
    {
          $scope.data3 = data3
    })
    })
    })
  }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM