После запроса Angular.js $http, вызов полной функции независимо от успеха или неудачи обещания

Как я могу гарантировать, что функция complete() будет выполняться независимо от результата вызова $http с помощью API обещаний, предоставляемого с помощью 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
});

Можно использовать это, чтобы скрыть значок Spinner AJAX после завершения запроса. Вы хотели бы спрятать счетчик, независимо от результата запроса.

Ответ 1

Я не лучший мировой эксперт в Angular.js, но понимаю, что вы можете сделать следующее:

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

Вы по существу вынуждены что-то изобретать из одного или нескольких .then(), который является методом $q обещания только.

Ответ 2

Это зависит от того, что вы хотели бы сделать, но для логики очистки и т.д. вы также можете использовать finally() для запуска либо на выполнение или отказ от вашего обещания:

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

Обратите внимание, что хотя finally() поддерживается $q (и некоторыми другими библиотеками), не является частью официального отчета .

Ответ 3

Если вам все равно, успешный запрос или нет, вы можете передать тот же обратный вызов на success и 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);

Но имейте в виду, что обратные вызовы success и error имеют другую подпись, чем обратные вызовы then.

Кроме того, promises распознается механизмом шаблонов в angular, что означает, что в шаблонах вы можете рассматривать promises, прикрепленные к области видимости, как если бы они были результирующими значениями.

Это означает, что вы можете сделать это:

Контроллер:

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

Шаблон:

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

И представление будет обновляться, когда обещание $http.get было разрешено.