承诺使用的模式仍然让我感到困惑。
例如,在Angular应用程序中,我有一个方法usersService
的服务emailExists(email)
。显然,它会向服务器执行请求,以检查给定的电子邮件是否已经存在。
我很自然地让方法emailExists(email)
返回在正常操作中解析为true
或false
的承诺。如果我们只有一些意外错误(例如,服务器返回500: internal server error
,那么应该拒绝promise,但在正常操作中,它会被解析为相应的布尔值。
Hovewer,当我开始实现我的异步验证器指令($asyncValidators
)时,我发现它想要解决/拒绝承诺。所以,到现在为止,我最终得到了这个相当丑陋的代码:
'use strict';
(function(){
angular.module('users')
.directive('emailExistsValidator', emailExistsValidator);
emailExistsValidator.$inject = [ '$q', 'usersService' ];
function emailExistsValidator($q, usersService){
return {
require: 'ngModel',
link : function(scope, element, attrs, ngModel) {
ngModel.$asyncValidators.emailExists = function(modelValue, viewValue){
return usersService.emailExists(viewValue)
.then(
function(email_exists) {
// instead of just returning !email_exists,
// we have to perform conversion from true/false
// to resolved/rejected promise
if (!email_exists){
//-- email does not exist, so, return resolved promise
return $q.when();
} else {
//-- email already exists, so, return rejected promise
return $q.reject();
}
}
);
};
}
}
};
})();
这让我觉得我应该修改我的服务,以便它返回已解决/拒绝的承诺。但是,对我来说这感觉有点不自然:在我看来,被拒绝的承诺意味着“我们无法得到结果”,而不是“否定结果”。
或者,我是否误解了承诺的用法?
或者,我应该提供两种方法吗?如何命名它们的常见模式是什么?
感谢任何帮助。
答案 0 :(得分:2)
在这种情况下,没有正确/不正确的方法解决此问题。您对电子邮件检查服务的评价听起来很合理:事实上,数据库中电子邮件的存在并不严格意味着失败情况,承诺拒绝通常对应并反映。
另一方面,如果你考虑一下,Angular实现异步验证器的方式也是有意义的。失败的验证结果在概念上感觉像是失败,不是在HTTP方面,而是在业务逻辑意义上。
所以在这种情况下,我可能会调整我的自定义服务,至少返回非成功状态,例如409 Conflict。
如果你仍想要返回200个成功代码以及真/假共鸣,你仍然可以使验证码变得不那么难看:
ngModel.$asyncValidators.emailExists = function (modelValue, viewValue) {
return usersService.emailExists(viewValue).then(function (email_exists) {
return $q[email_exists ? 'when' : 'reject']();
});
};