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

Node后端如何存储request请求返回值以完成批量接口调用?

解决Node.js中异步request请求结果无法存储的问题

你遇到的核心问题是异步代码的执行顺序问题:request是基于回调的异步函数,当你尝试把回调里的sum赋值给外部变量theSum时,回调函数还没执行(请求还没完成),所以theSum根本拿不到正确的值。而且回调里的return sum只能返回给request内部,没法传递到外部作用域。

下面给你两种靠谱的解决方案,都是用Promise + async/await来处理异步逻辑,让代码更清晰,同时能正确收集所有请求结果:


方案一:将request封装为Promise,并行处理所有请求(高效)

首先把回调式的request包装成Promise,这样就能用async/await来等待请求完成:

const request = require('request');

// 封装request为Promise函数,传入请求配置和费率,返回计算后的sum
function fetchAndCalculateSum(options, theRate) {
  return new Promise((resolve, reject) => {
    request(options, (error, response, body) => {
      if (error) {
        // 请求失败时抛出错误
        return reject(new Error(`Request failed: ${error.message}`));
      }
      
      console.log(`Response: ${response.statusCode} ${response.statusMessage}`);
      
      try {
        const bodyData = JSON.parse(body);
        const sum = bodyData.fields.timetracking.originalEstimateSeconds / 3600 * theRate;
        // 请求成功时返回计算后的sum
        resolve(sum);
      } catch (parseError) {
        // 处理JSON解析错误
        reject(new Error(`Failed to parse response: ${parseError.message}`));
      }
    });
  });
}

然后在你的接口路由里,用async/await结合Promise.all来并行处理所有Adhoc数据的请求,最后收集结果返回:

// 假设这是你的Express路由处理函数(需要标记为async)
app.get('/your-adhoc-sum-api', async (req, res) => {
  try {
    // 1. 从数据库获取所有Adhoc数据的_id(这里假设用MongoDB的Mongoose,你可以换成自己的数据库查询逻辑)
    const adhocList = await Adhoc.find({}, { _id: 1 }); // 只查询_id字段,提升效率

    // 2. 为每个Adhoc生成请求Promise
    const sumPromises = adhocList.map(async (adhoc) => {
      // 根据当前adhoc的_id构建request的配置(这里需要你补充具体的url和其他参数)
      const requestOptions = {
        url: `https://your-target-api.com/data/${adhoc._id}`, // 示例URL
        method: 'GET',
        headers: {
          // 如果需要请求头,比如Authorization,在这里添加
        }
      };

      // 等待当前请求完成,拿到sum值
      const sum = await fetchAndCalculateSum(requestOptions, theRate); // theRate是你的费率变量

      // 返回需要的格式对象
      return { id: adhoc._id.toString(), sum }; // 把ObjectId转为字符串,方便前端处理
    });

    // 3. 等待所有请求完成,拿到所有结果
    const finalResult = await Promise.all(sumPromises);

    // 4. 返回结果给前端
    res.json(finalResult);
  } catch (error) {
    // 处理所有可能的错误(数据库查询失败、请求失败、JSON解析失败等)
    console.error('API Error:', error);
    res.status(500).json({ message: 'Internal Server Error', error: error.message });
  }
});

方案二:顺序处理请求(适合有API频率限制的场景)

如果你的目标API有请求频率限制,不想同时发起太多请求,可以用for...of循环顺序执行每个请求:

app.get('/your-adhoc-sum-api', async (req, res) => {
  try {
    const adhocList = await Adhoc.find({}, { _id: 1 });
    const finalResult = [];

    // 用for...of顺序遍历,确保前一个请求完成后再发下一个
    for (const adhoc of adhocList) {
      const requestOptions = {
        url: `https://your-target-api.com/data/${adhoc._id}`,
        // 其他配置...
      };

      const sum = await fetchAndCalculateSum(requestOptions, theRate);
      finalResult.push({ id: adhoc._id.toString(), sum });
    }

    res.json(finalResult);
  } catch (error) {
    console.error('API Error:', error);
    res.status(500).json({ message: 'Internal Server Error', error: error.message });
  }
});

为什么这样能解决问题?

  • Promise把异步回调转换成了可以被await等待的对象,让异步代码的执行顺序变得可控。
  • async/await让异步代码看起来和同步代码一样直观,避免了回调嵌套(回调地狱)。
  • Promise.all可以并行处理所有请求,大幅提升接口响应速度;而for...of则适合需要严格顺序的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:50:16