我遇到的问题是$http
承诺没有从正在执行服务的服务中冒泡到任何调用服务方法的地方。
我在服务中有一个.authozire()
方法,它返回$http
Promise,如下所示:
// auth.service.js
function authorize(authParams) {
var request = {
method: 'POST',
url: _apiUrl + 'oauth/token',
data: authParams
};
return $http(request)
.then(
function successHandler(response) {
// Correctly executed when success
$log.debug('authService :: authorize => success', response);
},
function errorHandler(response) {
// Correctly executed when error
$log.debug('authService :: authorize => error', response);
}
);
}
上面的success
和error
方法(请注意,我已经不使用.success()
和.error()
方法,因为它们已被弃用)工作得很好在每种情况下,但是当我从控制器调用此方法时,它并没有按预期工作,如下所示:
// signin.controller.js
function submit() {
authService.authorize(vm.formData)
.then(
function successHandler(response) {
// Always executed even when there's an error
$log.debug('SignInController :: submit :: authService.authorize() => success', response);
},
function errorHandler(response) {
// NEVER executed
$log.debug('SignInController :: submit :: authService.authorize() => error', response);
}
);
}
第一种方法successHandler
总是被调用,即使出现错误且服务执行了自己的errorHandler
。
似乎Promise是由服务返回的,它只是一个接受.then()
的简单承诺,但并没有区别success
和fail
。在文档中:
返回Promise,当请求成功或失败时,将{{3}}解析为响应对象。
所以......我错过了什么吗?有没有人之前有这样的问题?
谢谢!
答案 0 :(得分:3)
在auth.service.js
中,errorHandler必须返回被拒绝的承诺:
return $q.reject(response);
答案 1 :(得分:3)
我相信当我了解承诺时,你会有类似的感受。以下是我提出的与您类似的问题的答案。我很惊讶错误不是传播。 Using Kris Kowal's Q. How should I catch if any errors have been thrown throughout the life of a chained promise?
引用这个答案:
处理的拒绝就像一个被捕获的例外。它停止传播 好吧,它被处理了。如果你想处理拒绝和 保持拒绝你需要再次重新抛出,就像在同步中一样 代码。
try {
throw new Error();
} catch(e){
// handle error
}
// no error here this code will keep running.
如果您希望它继续拒绝并处理它,您需要重新抛出:
try {
throw new Error();
} catch(e){
// handle error
throw e;
}
// this code will not run
与承诺相同,就像你写的一样。这不是特别的 奇怪的是承诺,这就是同步异常的工作原理。 如果你想传播 - 你重新投掷,否则 - 错误是 被视为处理。
return $q.reject(response);
来为链中的下一部分收到相同的错误。您也可以在服务结束时说throw response;
而不返回,它会将错误带到链的下一部分。我个人认为1,但那是因为当承诺未记录错误时我无法忍受,如果没有记录,很难找到破坏的内容。
答案 2 :(得分:0)
问题是您已经在验证服务中处理承诺的回调。
要解决此问题,我们有两种可能的解决方案:
在authorize方法中创建一个promise并将其返回。
function authorize(params) {
// create a promise object
var dfd = $q.defer();
var request = []; // request params here
$http(request).then(
function SuccessHandler(res) {
def.resolve(res);
},
function ErrorHandler(res) {
dfd.reject(res);
});
return dfd.promise();
}
另一种方法是发送http对象而不处理方法授权中的回调
return $http(request);