我有一个调用角度服务的方法,因此通过服务发出ajax请求。我需要确保如果多次调用它,则中止先前的请求(如果尚未解决的话)。
此方法可以多次调用。此方法实际上来自ngTableParams
上的ngTable:
getData = function($defer, params) {
myService.getRecord(params).then(function(res){
...
$defer.resolve(res.Records);
});
}
以下是该服务的方法:
this.getRecords = function(params) {
...
return Restangular
.all('/api/records')
.post(filters);
};
如果ngTable进行3次调用,我希望中止前2次(除非它们返回得太快以至于它已经解决)
答案 0 :(得分:25)
您可以通过$http
配置属性中止timeout
调用,该属性可以是Promise,在解析后中止请求。
所以在restangular中,你可以这样做
var abort = $q.defer();
Restangular.one('foos', 12345).withHttpConfig({timeout: abort.promise}).get();
abort.resolve();
例如,要将其与您的用例集成,您可以在服务中使用它:
var abortGet;
this.getRecords = function(params) {
...
if (abortGet) abortGet.resolve();
abortGet = $q.defer();
return Restangular
.all('/api/records')
.withHttpConfig({timeout: abortGet.promise})
.post(filters);
}
这样调用getRecords
总是会中止之前的调用,如果尚未解决的话!
希望这有帮助!
答案 1 :(得分:1)
如果您想在更改UI路由器的状态时中止所有http请求,这是另一种方法:
angular
.run(function(HttpHandlerSrv) {
HttpHandlerSrv.abortAllRequestsOn('$stateChangeSuccess');
HttpHandlerSrv.R.setFullRequestInterceptor(function(element, operation, route, url, headers, params, httpConfig) {
httpConfig = httpConfig || {};
if(httpConfig.timeout === undefined) {
httpConfig.timeout = HttpHandlerSrv.newTimeout();
}
return { element: element, params: params, headers: headers, httpConfig: httpConfig };
});
})
.factory('HttpHandlerSrv', HttpHandlerSrv);
/** ngInject */
function HttpHandlerSrv($q, $rootScope, Restangular) {
var requests = [];
return {
R: Restangular,
newTimeout: newTimeout,
abortAllRequests: abortAllRequests,
abortAllRequestsOn: abortAllRequestsOn
};
function newTimeout() {
var request = $q.defer();
requests.push(request);
return request.promise;
}
function abortAllRequests() {
angular.forEach(requests, function(request) {
request.resolve();
});
requests = [];
}
function abortAllRequestsOn(event) {
$rootScope.$on(event, function(event, newUrl, oldUrl) {
if(newUrl !== oldUrl) { abortAllRequests(); }
});
}
}