如何获得在承诺链中成功的第一个承诺的价值
How to get the value of the first promise that succeeds in a chain of promises
我正在寻找一种仅在另一个承诺失败时才返回承诺的方法。
我该怎么做?
我的承诺看起来像这样(当然我已经删除了不相关的代码(:
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
,如果它拒绝,则拒绝整个链
到目前为止,我已经这样做了,它似乎有效。(我正在使用什么时候.js顺便说一句(
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) }
);
所以这段代码有效,但我很确定应该有更优雅的方式来做到这一点(我认为我的代码看起来更像是一个黑客(。
像这样的事情呢:
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
继续链条。承诺构造函数几乎没有用处。 - 您可以通过执行
.then(null, function(){...
来省略.then
中的第一个参数,但是使用.catch
是该参数的别名更简单。更一般地说,.then
忽略不是函数的参数。
拒绝 - 和返回值传播,如果你不通过
.catch
(或.then
的第二个参数(处理拒绝,它将简单地跨链移动,直到你这样做。返回值也是如此 - 这就是为什么这里的前两行包含:- 尝试通过用户名获取用户
- 如果失败,请尝试通过电子邮件。
一般来说,你所描述的内容在同步代码中与承诺和异常相似是非常常见的。学习如何有效地做这种事情很重要。
相关文章:
- 在另一个函数成功结束后调用该函数
- 一个承诺换多个承诺-并发问题
- WinJS,从可能是异步的函数返回一个承诺,也可能不是异步的
- 在jQuery中,.state()如何确定一个承诺是挂起的、已解决的还是被拒绝的
- 转换嵌套'对于'循环成一个承诺,为了一个承诺?嵌套承诺
- 只有在前一个功能成功完成的情况下,我才能正确地启动此功能
- 同步函数调用涉及post-json调用,其中一个函数应该在另一个函数成功后成功
- 如何通过Bluebird承诺您自己的javascript api,该api使用另一个承诺的api
- jasmine 2.0测试angularjs的工厂方法,这是一个承诺
- 如何获取 Ember 组件对象内部承诺成功或错误回调
- 做一些 ajax 并使用 getJSON 返回一个承诺
- 在 AngularJS 中声明一个承诺,并带有命名的成功/错误回调
- 链承诺.all 与从上一个承诺返回的数组.all.
- 如何更好地停止一个承诺链并开始另一个承诺链
- 同时循环承诺,直到另一个承诺结束
- 在angular.extend()中向变量返回一个承诺的值
- 茉莉花单元测试模拟一个承诺
- 我能不能早点结束一个承诺
- 如何使用 Parse.promise javascript 定义一个承诺数组并获取结果数组 [parse.com]
- Angular的承诺(关于一个承诺?)或者如何在$http之后链接一个.then.成功的角度