Express.js接口res.send返回空数组但循环内console.log输出正确如何解决
问题原因
核心是异步执行顺序错误:
forEach传入的异步回调不会被外层的async/await等待,所有内部的数据库查询还没执行完成,代码就已经走到了res.send(offers),此时offers还是初始空数组。控制台能打印出预期结果,是因为控制台打印操作是异步的,你查看打印结果时内部异步查询已经完成,填充了offers数组。
修复方案
将所有异步查询的 Promise 收集起来,用 Promise.all 统一等待全部执行完成后再返回结果,同时优化原逻辑中重复查询数据库的问题,修复后代码如下:
offers: async (req, res) => { let orders = await req.models.order.find({ "customers.customer_id": req.user._id, }); let cashbacks = await req.models.cash_backs .find() .populate("restaurant_id"); let offers = []; // 收集所有异步查询任务 const queryTasks = []; for (let i = 0; i < cashbacks.length; i++) { const currentCashback = cashbacks[i]; // 每个返现活动仅查询一次用户使用次数,无需循环orders重复查询 queryTasks.push( req.models.order .find({ "customers.customer_id": req.user._id, cash_back_id: currentCashback._id, }) .then((result) => { const allowCount = currentCashback.per_visit.values.length; if (allowCount > result.length) { offers.push(currentCashback); } }) ); } // 等待所有查询任务执行完成后再返回结果 await Promise.all(queryTasks); res.send(offers); },
优化说明
- 原逻辑中循环
orders发起查询,会导致同一个返现活动被重复查询多次,优化后每个返现活动仅查询1次,大幅减少数据库请求量,提升接口性能 - 用
Promise.all统一等待异步任务,保证返回给客户端的是完全填充后的优惠数组
内容的提问来源于stack exchange,提问作者Amin Azimi
相关产品推荐
相关产品推荐

