我正在寻找一种方法,只有在另一个承诺失败时才能返回承诺。
我该怎么做?
我看起来像这样的承诺(当然我删除了非相关代码):
getUserByUsername = function(username) {
return promise(function(resolve, reject) {
user = userModel.getByUsername(username);
if ( user ) { resolve(user); } else { reject("user not found"); }
});
};
getUserByEmail = function(email) {
return promise(function(resolve, reject) {
user = userModel.getByEmail(email);
if ( user ) { resolve(user); } else { reject("user not found"); }
});
};
checkPassword = function(user, password) {
return promise(function(resolve, reject) {
if ( user.isValidPassword(password) ) { resolve() } else { reject("password mismatch"); }
});
};
我希望按以下顺序组合它们
getUserByUsername
,如果拒绝,请致电getUserByEmail
checkPassword
,如果拒绝,则拒绝整个链到目前为止,我已经完成了这项工作并且似乎有效。 (我正在使用when.js btw)
getUserByUsername(usernameOrEmail)
.then(
function(user) { return user; },
function() { return getUserByEmail(usernameOrEmail) }
)
.then( function(user) { return checkPassword(user, password) } )
.done(
function() { console.log('success'); },
function(err) { console.log('failure', err) }
);
所以这段代码有效,但我很确定应该有更优雅的方式(我认为我的代码看起来更像是黑客)。
答案 0 :(得分:6)
如下:
getUserByUsername(usernameOrEmail).
catch(getUserByEmail.bind(null, usernameOrEmail)).
then(function(user){
if(!isValidPassword(user, password)) throw new Error("Invalid Password");
}).then(function(){
// success
}, function(){
//fail
});
关键词:
throw
拒绝承诺,return
继续保留链。 promise构造函数几乎没用。.then
省略.then(null, function(){...
中的第一个参数,但使用.catch
更为简单,因为.then
是别名。更一般地说,.catch
会忽略不是函数的参数。.then
(或{{1}}的第二个参数)处理拒绝,它将直接移动到链中,直到您这样做。返回值也是如此 - 这就是为什么这里的前两行包含:
一般来说,您所描述的内容与同步代码中的异常的承诺和异常非常相似。学习如何有效地完成这类工作非常重要。