[英]Cancel / Abort all pending requests in angularJs
On route change, I need to abort ALL pending requests from previous route so that I don't run into problems of responses from previous route messing up data on my current route (it happens sometimes when responses from previous route take long time to finish). 在路由更改时,我需要中止来自先前路由的所有待处理请求,以便我不会遇到先前路由的响应问题,从而弄乱我当前路由上的数据(有时候,当前一路由的响应需要很长时间才能完成时) 。
I have thought about using http interceptor for this: 我曾考虑过使用http拦截器 :
$httpProvider.interceptors.push(function($q) {
return {
'request': function(config) {
},
'response': function(response) {
}
};
});
In the request function, I could modify the config.timeout
with a promise as suggested here and store all the deferred objects in a global cache so that I could cancel all of them. 在请求函数中,我可以使用此处建议的promise修改
config.timeout
,并将所有延迟对象存储在全局缓存中,以便我可以取消所有这些。
The problem with this approach is that it may override config.timeout
set in other places in the code. 这种方法的问题在于它可能会覆盖代码中其他位置设置的
config.timeout
。
I think another solution could be to cancel all ajax requests at XMLHttpRequest
level, but I don't know how to do it. 我认为另一种解决方案可能是取消
XMLHttpRequest
级别的所有ajax请求,但我不知道该怎么做。
Any suggestions? 有什么建议么? Thanks.
谢谢。
As you say, timeout
is the only API we have of use right now to cancel a running $http request. 正如你所说,
timeout
是我们现在用来取消正在运行的$ http请求的唯一API。 I think you're right on the money with an interceptor coupled with a cancel promise. 我认为你的拦截器加上取消承诺是对的。
What you could do is attach the full deferred object on the $http
request, and cancel all pendingRequests in your route change handler. 您可以做的是在
$http
请求上附加完整的延迟对象,并取消路由更改处理程序中的所有pendingRequests 。
Something like this could (perhaps*) work? 像这样的东西可能(或许*)有效吗?
angular.module('module').config(function ($httpProvider) {
$httpProvider.interceptors.push(function ($q) {
return {
request: function (config) {
if (!config.timeout) {
config.cancel = $q.defer();
config.timeout = config.cancel.promise;
}
return config;
}
}
});
});
angular.module('module').run(function ($rootScope, $http) {
$rootScope.$on('$stateChangeStart', function () {
$http.pendingRequests.forEach(function (pendingReq) {
if (pendingReq.cancel) {
pendingReq.cancel.resolve('Cancel!');
}
});
});
});
*: I say perhaps, because I had success with this approach, but it's seldom you find a silver bullet to something like this. *:我或许也许说,因为我采用这种方法取得了成功,但很少你能找到类似这样的银弹。
edit 编辑
If you need to bypass the error handler of the cancelled promise, hook into responseError
property and do manual labour there. 如果您需要绕过已取消的promise的错误处理程序,请挂钩到
responseError
属性并在那里进行手工操作。
angular.module('module').config(function ($httpProvider) {
$httpProvider.interceptors.push(function ($q) {
return {
responseError: function (response) {
if (response.config.timeout.$$state.value === 'Cancel!') {
// debugger;
return $q.when('bypassed');
}
}
}
});
});
I'm starting to think that there is no generic/'cool' solution to reach the end result you desire. 我开始认为没有通用/“酷”的解决方案来达到你想要的最终结果。 Treading some odd ground here : )
在这里走一些奇怪的地方:)
edit2: EDIT2:
Testing the above myself now. 现在自己测试一下。 Returning
$q.when('something')
in the responseError
will effectively bypass the error callback of the cancelled $http
request. 在
responseError
返回$q.when('something')
将有效地绕过已取消的$http
请求的错误回调。 Let me know if it works out for you. 如果它适合您,请告诉我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.