Reputation: 1594
I'm not experienced with Javascript promises and recently I started using promises instead of callbacks in my Javascript projects.
When I tried to run several promise functions one after another I landed in a nested chaos of then(). The code works exactly as expected, but my question is that if this is the way to resolve several promise functions one after another then what is the advantage of using promises instead of callbacks.
If I'm not doing it the right way, then it is a request from you guys to show me the proper way of resolving nested promises.
Below is my code that I don't like it they way it looks:
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));
};
Upvotes: 3
Views: 3455
Reputation: 227
If you prefer to use the then catch
structure, in order to take fully advantage of it I recommend you not to nest them. Of course you can, but then you should put a .catch()
after each of them. That's why the async
introduction made an easier code to read and handle errors, as it simplifies it with the try catch
structure.
If you pipe multiple .then()
, you can return a value as a promise from each of them that can be used inside the next one once the promise resolves. The only thing is that you loose these values unless you save them either in req
with new properties or in variables declared outside the pipe of .then()
.
That's why, in this snippet, I declared all the variables at the beginning in order to save all the values and use them in the final 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));
};
Upvotes: 6
Reputation: 3642
You can use async/await
structure for better formatting
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)
}
You should try to minimize the amount of async
calls you make in a function as it will impact your performance.
Upvotes: 3