蓝鸟承诺 - 嵌套与拒绝模式
Posted
技术标签:
【中文标题】蓝鸟承诺 - 嵌套与拒绝模式【英文标题】:Bluebird promises - nesting vs rejecting pattern 【发布时间】:2015-05-17 18:23:13 【问题描述】:我正在开发一个我们使用 Promise 的应用程序。我正在尝试找出更好的模式是什么。
打破 thenables 之间的关注点并在错误时拒绝承诺。然后在 catch 块中处理拒绝。还是在catch块中throw
一种新型错误和句柄更好?
Account.findOneAsync(email: request.payload.email)
.then(function (user)
if (user)
return user.compareHash(request.payload.password);
else
// Account not found
return Bpromise.reject('AccountNotFound');
)
.then(function (validPassword)
if (validPassword)
return request.auth.jwt.user.sign();
else
// Invalid password
return Bpromise.reject('InvalidPassword');
)
.then(function (jwt)
var response = reply.success();
return response.header('authorization', jwt);
)
.catch(function (e)
if (e === 'AccountNotFound' || e === 'Invalid Password')
return reply(Boom.unauthorized('Invalid username/password'));
else
// Perhaps log something like unhandled error
return reply(Boom.unauthorized('Invalid username/password'));
);
或嵌套有希望。我觉得这只是在“回调地狱”的同一个兔子洞。
Account.findOneAsync(email: request.payload.email)
.then(function (user)
if (user)
user.compareHash(request.payload.password)
.then(function (valid)
if (valid)
request.server.plugins.jwt.sign()
.then(function (jwt)
var response = reply.success();
return response.header('authorization', jwt);
);
else
// Invalid password
return reply(Boom.unauthorized('Invalid username/password'));
);
else
// Account not found
return reply(Boom.unauthorized('Invalid username/password'));
)
.catch(function (e)
console.log(e);
);
【问题讨论】:
您认为第二种方法有什么好处吗?第一个对我来说看起来好多了。 好吧,如果我采用第一种方法,我想知道什么更好。抛出一个新的错误或拒绝承诺。我想如果我抛出一个错误,我需要将 Error() 子类化以产生像“throw new AccountNotFound()”这样的错误 正如我在几秒钟前发布的答案中所说的那样,我认为惯用的做法是抛出一个错误。没有必要继承 Error。 Error 构造函数接受一个可以使用e.message
进行检查的消息字符串。
所以我现在看到你在第二种方法中得到了什么。您直接将无效结果转换为Boom.unauthorized
s,而不是抛出错误只是为了在之后将其更改为响应。我会考虑这个...
另见Handling multiple catches in promise chain
【参考方案1】:
我认为你可以通过投掷然后接住你的吊杆来获得两全其美的效果。
在这两种方法中你缺少的一件事是,当你已经在 then
处理程序中时,惯用的做法是抛出一个错误,而不是创建并返回一个被拒绝的承诺。在return
语句之后也不需要else
块:
Account.findOneAsync(email: request.payload.email)
.then(function (user)
if (user)
return user.compareHash(request.payload.password);
// Account not found
throw Boom.unauthorized('Invalid username/password');
)
.then(function (validPassword)
if (validPassword)
return request.auth.jwt.user.sign();
// Invalid password
throw Boom.unauthorized('Invalid username/password');
)
.then(function (jwt)
var response = reply.success();
return response.header('authorization', jwt);
)
.catch(function (e)
if (e.isBoom)
return reply(e);
// Perhaps log something like unhandled error
return reply(Boom.unauthorized('Invalid username/password'));
);
【讨论】:
我实际上不得不在第一个 thenable 中测试 request.auth.jwt.user.sign()。主要是因为我在签署 jwt 时需要访问用户对象。鉴于 Promise 规范不允许返回多个值,我觉得以这种方式实现更安全。以上是关于蓝鸟承诺 - 嵌套与拒绝模式的主要内容,如果未能解决你的问题,请参考以下文章