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

如何等待批量请求及Promise全部完成后再执行回调函数?

问题分析与解决方案

首先,你的核心问题是外层的Promise.all没有等待内部每个item的三个请求完成——因为你在map的async函数里,没有返回内部Promise.all([promise, promise1, promise2])的结果,导致每个map迭代都默认返回了一个resolved为undefined的Promise,外层Promise.all自然会提前完成,拿到的是全是undefined的数组。

另外还有一个隐藏的竞态风险:你正在修改共享的connection对象的reporting_period属性,但map是并行执行的,多个item的请求会同时修改这个属性,可能导致请求参数混乱(比如第一个item的三个请求可能都用了最后一次设置的nextYear)。

下面是修复并优化后的代码:

async function requestJahrStatistic(jahreStatistic, callback){
  // 封装请求逻辑,避免重复代码,同时避免共享connection的竞态问题
  const sendPeriodRequest = async (item, period) => {
    // 复制connection对象,避免多个请求互相干扰
    const conn = {...connection};
    conn.statistic_id = item.statistic_id;
    conn.reporting_period = period;
    
    return new Promise((resolve, reject) => {
      sendHTTPRequest(item, (result) => {
        resolve(result);
      }, (error) => {
        // 别忘了处理错误,否则Promise会一直pending
        reject(error);
      });
    });
  };

  // 外层Promise.all等待所有item的请求组完成
  const allResults = await Promise.all(
    jahreStatistic.map(async (item) => {
      const periods = getReportingPeriod(item.period);
      // 发起当前item的三个请求,等待全部完成后返回结果数组
      return Promise.all([
        sendPeriodRequest(item, periods.prevYear),
        sendPeriodRequest(item, periods.actualYear),
        sendPeriodRequest(item, periods.nextYear)
      ]);
    })
  );

  // 所有请求完成后调用回调
  callback(allResults);
}

关键改动说明:

  1. 返回内部Promise.all的结果:在map的async函数里,直接return Promise.all([...]),这样外层Promise.all才能收集到每个item的三个请求结果数组。
  2. 封装请求函数并隔离connection:创建sendPeriodRequest函数,每次请求都复制一个独立的connection对象,避免并行修改导致的参数混乱。
  3. 添加错误处理:给sendHTTPRequest加上错误回调,调用reject,避免某个请求失败时Promise一直pending。
  4. 简化async/await用法:用await替代嵌套的.then,让代码逻辑更线性易读。

如果你的sendHTTPRequest本身可以改造成返回Promise的形式,代码还能更简洁:

// 先把sendHTTPRequest包装成Promise版本
const sendHTTPRequestPromise = (item, conn) => {
  return new Promise((resolve, reject) => {
    sendHTTPRequest(item, resolve, reject);
  });
};

// 然后在requestJahrStatistic里直接用
async function requestJahrStatistic(jahreStatistic, callback){
  const allResults = await Promise.all(
    jahreStatistic.map(async (item) => {
      const periods = getReportingPeriod(item.period);
      const createConn = (period) => ({...connection, statistic_id: item.statistic_id, reporting_period: period});
      
      return Promise.all([
        sendHTTPRequestPromise(item, createConn(periods.prevYear)),
        sendHTTPRequestPromise(item, createConn(periods.actualYear)),
        sendHTTPRequestPromise(item, createConn(periods.nextYear))
      ]);
    })
  );

  callback(allResults);
}

这样整个逻辑更清晰,也彻底解决了并行请求的参数干扰问题,同时确保外层等待所有请求完成后再执行回调。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:09:40