我如何才能等到整批请求都发出并且承诺得到解决才能在回调函数上发送数据?

How can I wait until the whole batch of requests are made and the promises are solved before I send the data on the callback function?

我有一个包含 5 个项目的对象,每个项目将发送 3 次 http 请求。 我将其保存在

         var promise 
         var promise1 
         var promise2

最后,我正在解决(尝试)使用

的承诺
Promise.all([promise, promise1, promise2]]

然后我将数据发送到回调函数。

我正在使用 array.map() 在该数组上执行我的任务,所有请求和 Promise.all 都在其中发生。

如何才能等到整批请求都完成,promise都解决了才在回调函数上发送数据?

async function requestJahrStatistic(jahreStatistic, callback){
Promise.all(
     jahreStatistic.map(async (item) => {
      var periods = getReportingPeriod(item.period);

      connection.statistic_id = item.statistic_id;

      connection.reporting_period = periods.prevYear;
      var promise = new Promise(function(resolve, reject) {
        sendHTTPRequest(item, function(result) {
          resolve(result);
        });
      });

      connection.reporting_period = periods.actualYear;
      var promise1 = new Promise(function(resolve, reject) {
        sendHTTPRequest(item, function(result) {
          resolve(result);
        });
      });

      connection.reporting_period = periods.nextYear;
      var promise2 = new Promise(function(resolve, reject) {
        sendHTTPRequest(item, function(result) {
          resolve(result);
        });
      });

      Promise.all([promise, promise1, promise2]).then(async resolved => {
        var res = await resolved
        return res
      });
    })
  ).then(async resolved =>{
      var resp = await resolved;
      callback(resp)
  });

}

这是我在写问题之前尝试的最后一件事

该代码有几个问题:

  1. requestJahrStatistic 如果它通过调用回调

  2. 来报告其结果,则它不应该是 async
  3. 你在几个地方使用了这个模式:

    .then(async resolved => {
      var res = await resolved
      return res
    });
    

    这没有任何用处(除非...参见#5)并且可以完全删除。

  4. map 回调没有理由是 async,因为您没有在其中使用 await

  5. 你在承诺中重复你的逻辑包装 sendHTTPRequest,并且未能处理其中的错误。不要重复自己,为此做一个函数。

  6. 看起来 connection.statistic_idconnection.reporting_period 以某种方式被 HTTP 请求使用。他们不应该,那是远距离的怪异动作。 :-) 但如果它们是,那么 none 可以并行,因为您必须等待使用给定 statistic_id 和 [=22 的请求=] 完成后才能开始下一步。

  7. 您没有处理错误。

如果我假设 connection.reporting_period 被 HTTP 请求使用,这意味着它们不能重叠,所以 none 可以并行,你不能使用 Promise.all 为了它。你需要这样的东西:

如果 connection.reporting_period 未被 HTTP 请求使用 ,这可以全部并行:

function sendHTTPRequestP(item) {
    return new Promise((resolve, reject) => {
        sendHTTPRequest(item, result => {
            if (/*an error occurred*/) {
                reject(new Error(/*...*/));
            } else {
                resolve(result);
            }
        });
    })
}

// Completely serial because of spooky action at a distance with
// `connection.statistic_id` and `connection.reporting_period`
function requestJahrStatistic(jahreStatistic, callback) {
    Promise.resolve(async () => {
        const results = [];
        for (const item of jahreStatistic) {
            const periods = getReportingPeriod(item.period);
            connection.statistic_id = item.statistic_id;

            connection.reporting_period = periods.prevYear;
            const result1 = await sendHTTPRequestP(item);

            connection.reporting_period = periods.actualYear;
            const result2 = await sendHTTPRequestP(item);

            connection.reporting_period = periods.nextYear;
            const result3 = await sendHTTPRequestP(item);

            results.push([result1, result2, result3]);
        }
        return results;
    })
    .then(callback)
    .catch(error => {
        // Handle/report error, call `callback` with the appropriate error flag
    });
}

或者类似的东西。请注意,callback 将收到的是一个数组数组。外部数组将包含与 jahreStatistic 一样多的条目;这些条目中的每一个都将是三个 HTTP 调用结果的数组。

如果你能改变一些事情,让每个操作都接受参数而不是远距离的怪异动作(我看到 sendHTTPRequest 已经有 item 所以大概可以从中得到 statistic_id ,所以我们只需要通过 period),你就可以让事情并行:

function sendHTTPRequestP(item, reporting_period) {
    return new Promise((resolve, reject) => {
        sendHTTPRequest(item, reporting_period, result => {
            if (/*an error occurred*/) {
                reject(new Error(/*...*/));
            } else {
                resolve(result);
            }
        });
    })
}

function requestJahrStatistic(jahreStatistic, callback){
    Promise.all(
        jahreStatistic.map((item) => {
            const periods = getReportingPeriod(item.period);
            return Promise.all([
                sendHTTPRequestP(item, periods.prevYear),
                sendHTTPRequestP(item, periods.actualYear),
                sendHTTPRequestP(item, periods.nextYear)
            ]);
        })
    )
    .then(callback)
    .catch(error => {
        // Handle/report error, call `callback` with the appropriate error flag
    });
}

或者类似的东西。