You need to enable JavaScript to run this app. Express.js接口res.send返回空数组但循环内console.log输出正确如何解决
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 23:45:06