如何简化深度嵌套的承诺
How to simplify deep nested promises
我遇到了一种情况,我需要打破then()
中的每个"else"子句,这看起来并不比嵌套回调好,这是一个登录过程:
User.findOne({
username: username
}).exec()
.then(user => {
if (user) {
return user.verifyPassAsync()
.then(matched => {
if (matched) {
return User.getBriefProfile(username))
.then(emp => {
if (emp) {
return saveToSession(emp);
} else {
//return
}})
} else {
//return ...
}})
} else {
// return false
}
})
有什么方法可以简化它吗?
不完全是这样,因为这里嵌套的不仅是承诺,还有条件。如果使用async/await (ES7)编写,您的函数将看起来像
var user = await User.findOne({username}).exec();
if (user) {
var matched = await user.verifyPassAsync();
if (matched) {
var emp = await User.getBriefProfile(username);
if (emp) {
return saveToSession(emp);
} else {
// return …;
}
} else {
// return …;
}
} else {
// return …;
}
可以看到,嵌套是程序固有的。虽然它已经有点简化了(then
调用没有嵌套),你现在可以用Promise.coroutine
和ES6生成器做到这一点。
您最好的选择可能是在每个else
中throw
一个错误,并与之线性化链,最终.catch
。当然,如果您在每个else
块中做同样的事情,那么您也可以写入
var user = await User.findOne({username}).exec();
if (user)
var matched = await user.verifyPassAsync();
if (matched)
var emp = await User.getBriefProfile(username);
if (emp) {
return saveToSession(emp);
else
// return …;
很容易转换回then
回调:
User.findOne({username: username}).exec()
.then(user =>
user && user.verifyPassAsync()
).then(matched =>
matched && User.getBriefProfile(username);
).then(emp =>
emp ? saveToSession(emp) : …;
);
相关文章:
- 嵌套承诺会产生类似的效果
- 如何将嵌套设置超时转换为承诺
- 干净的代码和嵌套的承诺
- 蓝鸟承诺 - 嵌套与拒绝模式
- 如何展平嵌套承诺依赖项
- 余烬嵌套的路线和承诺
- 嵌套承诺
- 测试嵌套AngularJS与Jasmine的承诺
- 转换嵌套'对于'循环成一个承诺,为了一个承诺?嵌套承诺
- 嵌套承诺与q-io
- 如何将嵌套承诺与Q连锁?我可以'Don’我不能让它们按正确的顺序运行
- 在嵌套承诺链中重新引发异常
- 此代码中嵌套承诺的目的是什么
- 嵌套承诺执行不同步
- 嵌套的 AJAX 调用列表和 $.when.apply - 延迟承诺无法正常工作
- AngularJs $q.all 不会用混合的嵌套承诺来解决
- 使用模拟工厂在茉莉花中测试嵌套承诺
- angular.foreach 解析嵌套承诺
- 如何避免用$q嵌套承诺
- 使用请求-承诺的嵌套异步请求