在 Javascript Promise 中嵌套 .then() 和 catch

Mas*_*ood 4 node.js express sequelize.js

我对 Javascript Promise 没有经验,最近我开始在我的 Javascript 项目中使用 Promise 而不是回调。
当我尝试依次运行多个 Promise 函数时,我陷入了 then() 的嵌套混乱之中。代码完全按照预期工作,但我的问题是,如果这是依次解析多个 Promise 函数的方法,那么使用 Promise 而不是回调有什么优势。
如果我没有以正确的方式这样做,那么这是你们的请求,请向我展示解决嵌套承诺的正确方法。下面是我的代码,我不喜欢它的外观:

exports.editExpense = (req, res, next) => {
    Account.findAll().then(accounts => {
        Budget.findAll().then(budgets => {
            Expense.findAll().then(expenses => {
                Expense.findByPk(id).then(expense => {
                    res.render('expenses/index', {
                        urlQuery: urlQuery,
                        expenses: expenses,
                        expense: expense,
                        accounts: accounts,
                        budgets: budgets
                    });
                })
            })
        })
    }).catch(error => console.log(error));
};
Run Code Online (Sandbox Code Playgroud)

小智 5

如果您更喜欢使用该then catch结构,为了充分利用它,我建议您不要嵌套它们。当然可以,但是你应该在.catch()每个后面加一个。这就是为什么async引入使代码更容易阅读和处理错误,因为它简化了结构try catch

如果您通过管道传输多个.then(),则可以从每个值返回一个值作为承诺,一旦承诺解决,该值就可以在下一个值中使用。唯一的事情是您会丢失这些值,除非您将它们保存在req新属性中或保存在 管道外部声明的变量中.then()

这就是为什么在这段代码中,我在开头声明了所有变量,以便保存所有值并在最终结果中使用它们res

exports.editExpense = (req, res, next) => {
    
    let accounts;
    let budgets;
    let expenses;

    Account.findAll()
        .then(fetchedAccounts => {
            accounts = fetchedAccounts;
            return Budget.findAll()
        })
        .then(fetchedBudgets => {
            budgets = fetchedBudgets;
            return Expense.findAll()
        })
        .then(fetchedExpenses => {
            expenses = fetchedExpenses
            return Expense.findByPk(id)
        })
        .then(expense => {
            return res.render('expenses/index', {
                urlQuery: urlQuery,
                expenses: expenses,
                expense: expense,
                accounts: accounts,
                budgets: budgets
            });
        })
        .catch(error => console.log(error));
};
Run Code Online (Sandbox Code Playgroud)