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

如何将包含异步任务的for循环封装为Promise并等待所有任务完成

解决方案

你的问题核心是循环内的fetchData是异步操作,throttle包装后的执行也是非阻塞的,代码不会等待这些异步任务完成就直接执行了最后的callback。我们只需要把每个异步任务封装为Promise,收集所有Promise后用Promise.all等待全部执行完毕再触发回调即可。

修改后的完整代码如下:

const loop = (callback) => {
  // 收集所有异步任务的Promise
  const promises = [];
  for(const domain of domains) {
    // 每个domain的任务封装为Promise推入数组
    promises.push(new Promise((resolve) => {
      throttle(() => {
        fetchData(domain)
          .then((data) => {
            if (data[0]) {
              // 修正原代码中typeof的错误用法
              if (
                typeof data[1] === undefined ||
                typeof data[1]?.settings?.[1]?.protocol === undefined
              ) {
                // 此处可补充你的空分支逻辑
              } else {
                data = data[1];
                if (
                  data.settings[1].protocol != "IMAP" ||
                  providerExist(data.domain)
                ) {
                  return;
                }
                addProvider(
                  data.domain,
                  data.settings[1].address,
                  data.settings[1].port
                );
              }
            }
          })
          .catch((err) => {
            console.log(`${err}`);
          })
          .finally(() => {
            // 无论当前任务成功失败都标记完成,避免单个请求错误卡住整体流程
            resolve();
          });
      });
    }));
  }
  // 等待所有异步任务执行完成后再调用回调
  Promise.all(promises).then(() => callback());
}

注意事项

  • 原代码中typeof的使用存在语法错误,把整个判断表达式放进了typeof的参数中,导致判断逻辑完全不生效,上述代码已修正该问题,同时新增可选链避免深层属性读取时报错。
  • 如果你需要只有所有请求全部成功时才执行回调、出错就中断流程,可以去掉finally里的resolve,把resolve放到then逻辑的末尾,catch中调用reject即可。
  • 如果你使用的throttle函数本身支持返回Promise,可以直接返回节流函数的执行结果,不需要额外封装一层Promise。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 09:57:03