After Angular.js $http request, call complete func

2019-04-05 06:26发布

问题:

How can I ensure that the complete() function will run regardless of the outcome of the $http call using the promise API provided with Angular.js?

$http({
    method: 'POST',
    url: submitUrl,
    data: $scope.data
})
.success(function(data) {
      // execute this code on success
})
.error(function(data) {
      // execute this code on error
})
.complete(function() {
  // execute this code regardless of outcome
});

One could use this to hide an AJAX spinner icon once the request is complete. You would want to hide the spinner regardless of the request outcome.

回答1:

I'm not the world's greatest expert in Angular.js but understand you can do as follows :

whatever.then(function() {
    // success code here
}, function() {
    // error code here
    return true; // return anything that's not undefined (and not a `throw()`) to force the chain down the success path at the following then().
}).then(function() {
    // "complete" code here
});

You are essentially forced to contrive something from one or more .then(), which is a $q promise's only method.



回答2:

It depends on what you would like to do, but for clean-up logic and similar you may also use finally() to run either on fulfillment or rejection of your promise:

promise.finally(function () {
    // Do something regardless of outcome.
});

Please note that although finally() is supported by $q (and some other libraries) is not part of the official draft.



回答3:

If you don't care if the request is successful or not, then you can pass the same callback to success and error...

   var cb = function(response){
      // do something
   };


   $http.post(submitUrl, $scope.data).success(cb).error(cb);

   // OR

   $http.post(submitUrl, $scope.data).then(cb, cb);

But be aware that success and error callbacks have a different signature than the then callbacks.

  • http://docs.angularjs.org/api/ng.$http
  • http://docs.angularjs.org/api/ng.$q

Also, promises are recognized by the templating engine in angular, which means that in templates you can treat promises attached to a scope as if they were the resulting values.

This means that you can do this:

Controller:

$scope.article = $http.get('/articles/' + articleId);

Template:

<article ng-cloak>
   <h3>{{article.title}}</h3>
   <div>{{article.content}}</div>
</article>

And the view will update when the $http.get promise has been resolved.