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

Node.js中如何在For循环及所有异步操作完成后再返回接口响应

问题根因
  • 代码中调用的ExternalServer.GetAssetsOfUser、ExternalServer.GetPriceOfAsset均为异步Promise操作,原始写法未等待异步请求返回就直接执行了res.send(body),此时所有外部接口还未响应,自然返回空数组
  • 额外存在变量作用域错误:assetsArr定义在GetAssetsOfUser的回调函数内部,回调外的赋值语句userObj.assets = assetsArr根本无法访问到该变量,即便异步请求完成也不能正确赋值
修复方案

推荐使用async/await语法改写异步逻辑,配合Promise.all批量等待所有异步操作完成后再返回响应,修复后的代码如下:

app.get("/usersData", async (req, res) => {
  try {
    // 等待数据库查询用户列表完成
    const users = await Users.find({});
    // 批量等待所有用户的资产查询逻辑处理完成
    const body = await Promise.all(users.map(async (user) => {
      const userObj = { userName: user.userName, assets: [] };
      // 等待当前用户的资产查询接口返回
      const assets = await ExternalServer.GetAssetsOfUser(user.secretKey);
      // 过滤出余额大于50的资产
      const validAssets = Object.values(assets).filter(asset => asset.amount > 50);
      // 批量等待所有有效资产的价格查询完成
      const assetsArr = await Promise.all(validAssets.map(async (asset) => {
        const price = await ExternalServer.GetPriceOfAsset(asset.name);
        return {
          name: asset.name,
          value: +parseFloat(asset.amount).toFixed(4) * price
        };
      }));
      userObj.assets = assetsArr;
      return userObj;
    }));
    // 所有逻辑处理完成后再返回结果
    res.send(body);
  } catch (err) {
    // 统一捕获所有异步操作的异常,避免接口挂起
    res.status(500).send({ error: "数据查询失败" });
  }
})
逻辑说明
  • 所有异步操作前加await关键字,代码会等待该步骤执行完成后再往下走
  • Promise.all会并行处理多个同批次的异步请求,相比串行等待大幅提升查询效率
  • 外层增加try/catch统一捕获全链路异常,避免接口无响应或崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 19:27:05