javascript - 如何简化深层嵌套的 Promise

标签 javascript promise ecmascript-6 bluebird es6-promise

我遇到过一种情况,我需要在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
        }
    })

有什么办法可以简化这个吗?

最佳答案

并非如此,因为您(仅)在这里嵌套的不是 promise ,而是条件。如果使用 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抛出一个错误,并用它来线性化链,.catch在结尾。当然,如果您在每个 else block 中执行相同的操作,那么您也可以编写

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

关于javascript - 如何简化深层嵌套的 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32100122/

相关文章:

ReactJS - ES6 类 - 使用增强属性调用 super()

javascript - ES6 属性值简写 undefined

javascript - 限制html中的点击按钮

javascript - IE6友情提示

javascript - 获取元素的值一次然后保持该值静态

javascript - 使用 jQuery 解决循环中的 promise

javascript - 在滚动上固定/修复 Vanilla Javascript 中的多个元素

javascript - JS 问题然后创建一个计算器并能够输入多个数字

javascript - AWS Lambda 不等待来自 DynamoDB 的 Promise.all()

javascript - 如何让 promise 同步执行?