当promise被拒绝时,AngularJS服务重试

Ang*_*lin 15 javascript angularjs angularjs-service

我从我的控制器中的异步服务获取数据,如下所示:

myApp.controller('myController', ['$scope', 'AsyncService',
function($scope, AsyncService) {
    $scope.getData = function(query) {
        return AsyncService.query(query).then(function(response) {
            // Got success response, return promise
            return response;
        }, function(reason) {
            // Got error, query again in one second
            // ???
        });
    }
}]);
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 如何在没有返回承诺的情况下从服务中收到错误时再次查询服务.
  2. 在我的服务中这样做会更好吗?

谢谢!

M.K*_*afi 21

您可以在服务本身而不是控制器中重试请求.

所以,AsyncService.query可以是这样的:

AsyncService.query = function() {
  var counter = 0
  var queryResults = $q.defer()

  function doQuery() {
    $http({method: 'GET', url: 'https://example.com'})
      .success(function(body) {
        queryResults.resolve(body)
      })
      .error(function() {
        if (counter < 3) {
          doQuery()
          counter++ 
        }
      })
  }

  return queryResults.promise
}
Run Code Online (Sandbox Code Playgroud)

你可以在控制器中摆脱你的错误功能:

myApp.controller('myController', ['$scope', 'AsyncService',
  function($scope, AsyncService) {
    $scope.getData = function(query) {
      return AsyncService.query(query).then(function(response) {
        // Got success response
        return response;
      });
    }
  }
]);
Run Code Online (Sandbox Code Playgroud)

  • 可能想要一个计数器,如果服务器关闭,这将只是反复循环. (2认同)

Dor*_*ian 9

这实际上有效:

angular.module('retry_request', ['ng'])
  .factory('RetryRequest', ['$http', '$q', function($http, $q) {
    return function(path) {
      var MAX_REQUESTS = 3,
          counter = 1,
          results = $q.defer();

      var request = function() {
        $http({method: 'GET', url: path})
          .success(function(response) {
            results.resolve(response)
          })
          .error(function() {
            if (counter < MAX_REQUESTS) {
              request();
              counter++;
            } else {
              results.reject("Could not load after multiple tries");
            }
          });
      };

      request();

      return results.promise;
    }
  }]);
Run Code Online (Sandbox Code Playgroud)

然后只是一个使用它的例子:

RetryRequest('/api/token').then(function(token) {
  // ... do something
});
Run Code Online (Sandbox Code Playgroud)

在声明模块时必须要求它:

angular.module('App', ['retry_request']);
Run Code Online (Sandbox Code Playgroud)

在你的控制器:

app.controller('Controller', function($scope, RetryRequest) {
  ...
});
Run Code Online (Sandbox Code Playgroud)

如果有人想通过某种退避或随机时间来改进它来重试请求,那就更好了.我希望有一天像Angular Core这样的东西