鉴于以下两个$resource
示例:
var exampleOne = $resource('/path').save(objectOne);
exampleOne.$promise.then(function (success) {}, function (error) {});
var exampleTwo = $resource('/path').save(objectTwo);
exampleTwo.$promise.then(function (success) {});
[注意:示例2不包含错误处理程序]
位于所有$http
个请求之下的拦截器:
var interceptor = ['$location', '$q', function ($location, $q) {
function error(response) {
if (response.status === 400) {
return $q.reject(response);
}
else {
$location.path('/error/page');
}
return $q.reject(response);
}
return {
'responseError': error
};
}
$httpProvider.interceptors.push(interceptor);
当示例资源$promise.then()
不包含错误回调时,如何使拦截器不被拒绝?如果回调存在于exampleOne
中,那么我希望拒绝,但如果不是exampleTwo
,那么我希望重定向到错误页面,从而将条件更改为:
if (response.status === 400 && $q.unresolvedPromises.doIndeedExist()) { ...
为什么呢?因为我的项目中只有一些情况要求以用户友好的方式处理400
,所以我想消除许多重复的错误回调或者必须在拦截器中放置一个不常见的情况列表。我希望拦截器能够根据promise链中另一个处理程序的存在来决定。
答案 0 :(得分:2)
简单地说这是不可能的,你无法检测到某人是否会在将来的某个时刻附加处理程序,就像你能告诉你何时{{1}在一个函数中,它将被捕获在外面或不在外面。 但是,您可以完成的工作。
这不是一个'noob'问题',这是非常基础的:
throw
简单地说出第一种情况:
function foo()
throw new Error(); // I want to know if whoever is calling `foo`
// handles this error
}
您得到的是始终履行的承诺。但是,在第二种情况下,承诺可能会被拒绝。使用拒绝处理程序处理拒绝就像实际代码中的 exampleOne.$promise.then(function (success) {}, function (error) {});
一样 - 一旦处理它就不再被拒绝。
就个人而言,我不会在这里使用拦截器,而是使用资源使用模式,因为它的意图更清晰,你可以将它包装在一个函数中,因此它不会需要一个范围但是我像那个想法少。这就是我要做的事情
catch
让我们证明这很有趣。
我们假设我们获得了一个程序M的代码,我们创建一个新的承诺attempt(function(){
return $resource('/path').save(objectTwo).$promise.
then(function (success) {});
});
function attempt(fn){
var res = fn();
res.catch(function(err){
// figure out what conditions you want here
// if the promise is rejected. In your case check for http errors
showModalScreen();
}
return res; // for chaining, catch handlers can still be added in the future, so
// this only detects `catch` on the function passed directly so
// we keep composability
}
并替换M中的每个p
语句和M中的return
语句一个throw
并且还添加了return p.catch(function(){})
,当且仅当运行return p.catch(function(){})
终止时,处理程序才会添加到p
。所以简而言之 - 给定代码M我们已经构建了一种方法来查看它是否根据查找M
是否附加到catch
的问题的解决方案的存在而停止 - 所以这个问题至少是和the halting problem一样难。
答案 1 :(得分:0)
也许你可以推迟重定向,零超时并给错误处理程序,如果存在任何错误处理错误对象设置标志:
var interceptor = ['$q', '$timeout', function ($q, $timeout) {
function error(rejection) {
return $q.reject(rejection).finally(function () {
$timeout(function () {
if (rejection.errorHandled === true) {
alert('all is under control');
} else {
alert("Houston we've got problems");
}
}, 0); //zero timeout to execute function after all handlers in chain completed
});
}
return {
'responseError': error
};
}];
var exampleOne = $resource('/path').save(objectOne);
exampleOne.$promise.then(function (success) { }, function(error) {
error.errorHandled = true;
});