【发布时间】:2015-06-19 14:48:57
【问题描述】:
是否可以从then(...) 部分触发承诺链的catch(...) 部分?
例如,我发出一个 $http 请求并链接一些行为。 $http 解析成功,但是在处理数据后,很明显数据更适合错误情况,所以我们想激活错误处理程序。
问题是——我在两个地方使用了这个承诺链;一个在服务本身中,另一个在激活服务的控制器中。控制器是处理承诺链的catch(...) 部分的控制器,它会打开一个显示错误消息的模式。
到目前为止,我已经能够链接承诺,这样,每当在服务中触发 then(...) 或 catch(...) 时,我可以返回一个结果,然后它将在控制器中触发 --正如预期的那样。
但是我如何在服务中触发then(...),但返回结果使得catch(...) 将在控制器内触发?
我尝试使用$q.reject(...) 创建并返回一个新的promise,作为then(...) 函数中的返回值,但这似乎不起作用。
例子:
var url = 'http://google.com';
$http.get(url).then(handleFirst).then(handleSecond).catch(error);
function handleFirst (response) {
console.log("HandleFirstCalled", response);
return response;
}
function handleSecond (response) {
console.log("HandleSecondCalled", response);
return response;
}
function error (response) {
console.log("ErrorCalled", response);
}
你如何获得handleFirst(...),跳过执行handleSecond(...),而是执行error(...)?注意:您不能只调用error(response),因为外部承诺链无法访问它。
[编辑:] 找到了解决方案,return $q.reject(response); 确实有效。但是,服务catch(...) 函数必须始终为return $q.reject(response)。以前,我只有return response;,它将由控制器承诺链继续。但随后控制器会在其链中激活then(...)。
所以return response; 它去了:
Service -> $http -> then(...) -> catch(...) -> Controller -> then (...)
通过更改它return $q.reject(response); 它去:
Service -> $http -> then(...) -> catch(...) -> Controller -> catch (...)
【问题讨论】:
-
你需要展示你的一些代码。
return $q.reject(...)应该足够了 -
正如@Phil 所说 return $q.reject 应该工作,我今天早些时候回答了一个类似的问题stackoverflow.com/questions/30924047/…
-
$http.get(url).then(handleFirst).then(handleSecond, error)怎么样? -
@Phil @Chandermani 谢谢,它确实有效。我做错了。最初我做了类似
var deferred = $q.deferred; deferred.reject(response); return deferred.promise;的事情。我不知道你可以直接使用$q.reject(...)。 -
因此,如果 actual code 没有按照您的预期工作,为什么您应该始终在问题中使用它
标签: angularjs promise angular-promise