我对 Javascript 承诺没有经验,最近我开始在我的 Javascript 项目中使用承诺而不是回调。
当我试图一个接一个地运行几个 promise 函数时,我陷入了 then() 的嵌套混乱中。代码完全按预期工作,但我的问题是,如果这是一个接一个地解决多个承诺函数的方法,那么使用承诺而不是回调的优势是什么。
如果我没有以正确的方式做这件事,那么这是你们要求向我展示解决嵌套承诺的正确方法。
以下是我不喜欢的代码,它们的外观如下:
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));
};
答案 0 :(得分:3)
您可以使用 async/await
结构以获得更好的格式
exports.editExpense = async(req, res, next) => {
try {
let accounts = await Account.findAll();
let budgets = await Budget.findAll();
let expenses = await Expense.findAll()
let expense = await Expense.findByPk(id);
if (expense) {
res.render('expenses/index', {
urlQuery: urlQuery,
expenses: expenses,
expense: expense,
accounts: accounts,
budgets: budgets
});
} else {
console.log('else') //<<- Render/Handle else condition otherwise server will hang.
}
} catch (error) {
console.error(error)
}
您应该尽量减少在函数中进行的 async
调用数量,因为它会影响您的性能。
答案 1 :(得分:3)
如果您更喜欢使用 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));
};
def compared_with_top(self):
top = Pizza.objects.exclude(pk=self.pk).annotate(
tcount=Count('on_pizza')
).order_by('-tcount')
pizzas = Pizza.objects.filter(pk=self.pk).annotate(
tcount=Count('on_pizza')
).union(top[:3])