如何简化深层嵌套的诺言 [英] How to simplify deep nested promises

查看:85
本文介绍了如何简化深层嵌套的诺言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一种情况,我需要在then()中的每个"else"子句处打断,这看起来并不比嵌套回调好,这是一个登录过程:

I have come across a situation where I need to break at every "else" clause in a then(), and this doesn't look any better than nested callbacks, this is a login process:

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
        }
    })

有什么办法可以简化吗?

Is there any way I can simplify this?

推荐答案

并非如此,因为您不是(唯一)在这里嵌套应许,而是有条件的.如果使用async/await(ES7)编写,您的函数将如下所示:

Not really, as you're not (only) nesting promises here but rather conditionals. If written with async/await (ES7), your function would look like

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调用没有嵌套),您现在可以使用

As you can see, the nesting is inherent to your program. It's a bit simplified already though (no nesting for then calls), and you can do this right now with Promise.coroutine and ES6 generators.

您最好的选择是在每个else中出现一个throw错误,并以此对链进行线性化,最后.catch进行处理.当然,如果您在每个else块中都做相同的事情,那么您也可以编写

Your best bet might be to throw an error in each else, and linearise the chain with that, .catching it in the end. Of course, if you are doing the same thing in each else block, then you could as well write

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) : …;
);

这篇关于如何简化深层嵌套的诺言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆