如何在Node.js中将Mongoose查询结果赋值给本地变量并外部打印?
问题原因
Mongoose的find()是异步操作,你写的console.log(monthlyExpense)会在Expense.find()的回调函数执行前就运行,所以此时monthlyExpense还是初始的undefined,自然打印不出正确结果。
解决方案
方案1:用async/await写同步风格的异步代码(推荐)
把逻辑放在async函数里,用await等待每个查询完成,保证打印时变量已经被赋值:
// 比如在Express路由里,把处理函数声明为async app.get('/monthly-stats', async (req, res, next) => { try { // 查月度订单数据并求和 const orders = await CompleteOrders.find({ CompleteDate: { $gte: startDate, $lte: endDate } }); const monthlyOrders = lodash.sumBy(orders, o => o.Total); res.locals.income = monthlyOrders; // 查月度支出数据并求和 const expenses = await Expense.find({ ExpenseDate: { $gte: startDate, $lte: endDate } }); const monthlyExpense = lodash.sumBy(expenses, o => o.Expense); res.locals.Exp = monthlyExpense; // 现在打印就能得到正确值 console.log(monthlyExpense); // 顺便计算月度利润 const Profit_month = monthlyOrders - monthlyExpense; } catch (err) { next(err); } });
方案2:并行查询提升效率
如果两个查询互相不依赖,可以用Promise.all同时发起,节省等待时间:
app.get('/monthly-stats', (req, res, next) => { Promise.all([ // 同时发起两个查询 CompleteOrders.find({ CompleteDate: { $gte: startDate, $lte: endDate } }), Expense.find({ ExpenseDate: { $gte: startDate, $lte: endDate } }) ]) .then(([orders, expenses]) => { const monthlyOrders = lodash.sumBy(orders, o => o.Total); const monthlyExpense = lodash.sumBy(expenses, o => o.Expense); res.locals.income = monthlyOrders; res.locals.Exp = monthlyExpense; console.log(monthlyExpense); const Profit_month = monthlyOrders - monthlyExpense; }) .catch(err => next(err)); });
方案3:让数据库直接求和(性能最优)
没必要把所有订单/支出数据都查出来再在代码里求和,用Mongoose的聚合查询让数据库直接计算总和,减少数据传输量:
app.get('/monthly-stats', async (req, res, next) => { try { // 聚合查询订单总和 const orderAggregate = await CompleteOrders.aggregate([ { $match: { CompleteDate: { $gte: startDate, $lte: endDate } } }, { $group: { _id: null, totalIncome: { $sum: "$Total" } } } ]); const monthlyOrders = orderAggregate[0]?.totalIncome || 0; res.locals.income = monthlyOrders; // 聚合查询支出总和 const expenseAggregate = await Expense.aggregate([ { $match: { ExpenseDate: { $gte: startDate, $lte: endDate } } }, { $group: { _id: null, totalExpense: { $sum: "$Expense" } } } ]); const monthlyExpense = expenseAggregate[0]?.totalExpense || 0; res.locals.Exp = monthlyExpense; console.log(monthlyExpense); const Profit_month = monthlyOrders - monthlyExpense; } catch (err) { next(err); } });
内容的提问来源于stack exchange,提问作者Harsh Kataria
相关产品推荐
相关产品推荐

