How to simplify deep nested promises

浪尽此生 提交于 2019-12-02 05:24:27

问题


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?


回答1:


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 …;
}

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.

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

which easily translates back to then callbacks:

User.findOne({username: username}).exec()
.then(user =>
    user && user.verifyPassAsync()
).then(matched =>
    matched && User.getBriefProfile(username);
).then(emp =>
    emp ? saveToSession(emp) : …;
);


来源:https://stackoverflow.com/questions/32100122/how-to-simplify-deep-nested-promises

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!