You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数内数组非空但API返回空响应的原因及解决方法

问题原因与修复方案

问题原因

  • 核心问题是异步操作未等待完成就返回结果:你在userData?.selectedTrustees.map()中使用了async回调函数,map会立即返回一组Promise对象,但后续的console.log("response after", responseData)和res.json()并没有等待这些Promise执行完毕就直接运行了。
  • 内部的console.log能输出数据,是因为它处于异步回调的末尾,要等当前迭代里的User.findOne、Locations.findOne等异步操作完成后才会执行;而外部的代码逻辑不等待这些异步任务,所以返回时responseData还是初始的空数组。
  • 额外问题:代码同时混用了async/await和.then(),容易导致逻辑混乱,也加重了异步时序的问题。

修复步骤

  1. 用Promise.all()替代直接遍历map,因为Promise.all()会等待所有异步Promise执行完成后,再返回所有结果的数组。
  2. 让每个异步回调返回需要添加的对象,不再直接修改外部的responseData,最后通过Promise.all()的结果直接赋值给responseData。
  3. 统一使用async/await语法,去掉.then()嵌套,让代码逻辑更清晰。

修复后的代码

exports.getUserLocation = asyncHandler(async (req, res, next) => {
  const phone = req.params.phone;
  const userData = await User.findOne({ phone });
  if (!userData?.selectedTrustees) {
    return res.status(200).json({
      success: true,
      response: []
    });
  }

  // 用Promise.all等待所有异步操作完成
  const responseData = await Promise.all(userData.selectedTrustees.map(async (trustee) => {
    const data = await User.findOne({ phone: trustee.phone });
    if (!data) {
      // 可根据需求处理找不到受托人的情况,这里返回null后续过滤
      return null;
    }

    const locations = await Locations.findOne({ createdBy: trustee.phone });
    if (!locations) {
      return next(
        new ErrorResponse(
          `User with phone ${trustee.phone} doesn't have any location stored`
        )
      );
    }

    const locationHistoric = locations?.locationHistoric;
    const lastLocation = locationHistoric[locationHistoric.length - 1];

    if (trustee.sharedLocation === "true") {
      return {
        fullName: data?.fullName,
        id: data?._id,
        currentLocation: data?.currentLocation?.location,
        phone: data?.phone,
        status: data?.currentLocation?.status,
        createdAt: data?.currentLocation?.createdAt,
        share: "true",
      };
    } else {
      return {
        fullName: data?.fullName,
        id: data?._id,
        currentLocation: lastLocation?.location,
        phone: data?.phone,
        status: data?.currentLocation?.status,
        createdAt: lastLocation?.createdAt,
        share: "false",
      };
    }
  }));

  // 过滤掉可能的null值(比如找不到受托人的情况)
  const filteredData = responseData.filter(item => item !== null);

  console.log("response after", filteredData);
  res.status(200).json({
    success: true,
    response: filteredData,
  });
});

额外说明

  • 新增了userData?.selectedTrustees的判断,避免无受托人时出现逻辑错误。
  • 修正了错误提示的目标对象,把原代码的${phone}改为${trustee.phone},确保错误信息指向当前遍历的受托人。
  • 新增filteredData过滤无效的null值,避免返回无效数据。

内容的提问来源于stack exchange,提问作者bill2

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 21:40:19