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

如何实现函数在if/else间循环执行并保证异步代码有序?

问题描述

需要实现一个按顺序执行的异步函数,核心逻辑如下:

  • 遍历result.data中的每个d:
    1. 若d.connector == null,执行axios_Func,请求出错则重试(偶发错误,重试即可成功)
    2. 否则,判断d.name是否在dev对象中:
      • 存在则直接执行axios_DevFunc
      • 不存在则先执行axios_ProdFunc,完成后再执行axios_DevFunc

现有代码执行完全无序,所有操作混乱触发,需修正以保证执行顺序。原代码如下:

const mainFunc = (fn) => {
  return async (query_name, ...args) => {
    const result = await axios_Func(query_name);
    try {
      return fn(result, ...args);
    } catch (e) {
      console.log(e);
    }
  };
};

const createFunc = mainFunc((result, table_id) => {
  (async () => {
    let dev = await getTabs({ query: tables(123) });
    let prod = await getTabs({ query: tables(321) });
    result.data.forEach((d) => {
      if (d.connector == null) {
        axios_Func({ graphQL query }).then((response) => {
          if (response.data.errors) {
            // rerun function on errors
          } else console.log(JSON.stringify(response.data, null, 4));
        });
      } else {
        if (d.name in dev) {
          axios_DevFunc({ graphQL query }).then((response) => {
            console.log(`created from dev`);
            console.log(JSON.stringify(response.data, null, 4));
          });
        } else {
          axios_ProdFunc({ graphQL query }).then((response) => {
            .then((res) => res)
            .then((x) => {
              //repeat Dev Function after axios_ProdFunc is finished
              axios_DevFunc({ graphQL query }).then((response) => {
                console.log(`created from dev`);
                console.log(JSON.stringify(response.data, null, 4));
              });
            });
        }
      }
    });
  })();
});
解决方案

问题根源

  1. forEach是同步遍历,不会等待内部异步操作完成,导致所有请求同时触发
  2. 大量使用.then()嵌套,逻辑混乱且无法保证串行执行
  3. 缺少重试逻辑的具体实现
  4. 存在语法错误(axios_ProdFunc后多余的.then((res) => res))

修正方案

// 封装带重试逻辑的请求函数,可自定义重试次数
const axiosFuncWithRetry = async (config, maxRetries = 3) => {
  let retries = 0;
  while (retries < maxRetries) {
    try {
      const response = await axios_Func(config);
      if (response.data.errors) {
        throw new Error('GraphQL请求返回错误');
      }
      return response;
    } catch (e) {
      retries++;
      console.log(`请求失败,重试第${retries}次...`, e);
      if (retries >= maxRetries) throw new Error('重试次数耗尽,请求最终失败');
      // 重试前添加1秒延迟,避免频繁请求
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
  }
};

const mainFunc = (fn) => {
  return async (query_name, ...args) => {
    const result = await axios_Func(query_name);
    try {
      // 等待内部异步逻辑全部完成
      await fn(result, ...args);
    } catch (e) {
      console.log('mainFunc执行出错:', e);
    }
  };
};

const createFunc = mainFunc(async (result, table_id) => {
  // 先获取dev和prod数据,确保这两个请求完成后再处理后续逻辑
  const dev = await getTabs({ query: tables(123) });
  const prod = await getTabs({ query: tables(321) });

  // 用for...of遍历,保证每个元素的异步操作完成后再处理下一个
  for (const d of result.data) {
    if (d.connector == null) {
      try {
        const response = await axiosFuncWithRetry({ /* 填入你的GraphQL query */ });
        console.log(JSON.stringify(response.data, null, 4));
      } catch (e) {
        console.log('请求最终失败:', e);
      }
    } else {
      if (d.name in dev) {
        const response = await axios_DevFunc({ /* 填入你的GraphQL query */ });
        console.log(`created from dev`);
        console.log(JSON.stringify(response.data, null, 4));
      } else {
        // 先执行prod请求,完成后再执行dev请求
        await axios_ProdFunc({ /* 填入你的GraphQL query */ });
        const devResponse = await axios_DevFunc({ /* 填入你的GraphQL query */ });
        console.log(`created from dev`);
        console.log(JSON.stringify(devResponse.data, null, 4));
      }
    }
  }
});

关键改进点

  1. 串行遍历:用for...of替代forEach,确保每个元素的异步操作完成后再处理下一个
  2. 重试逻辑:封装axiosFuncWithRetry,自动处理偶发错误的重试
  3. 异步逻辑扁平化:用await替代所有.then()嵌套,逻辑更清晰,执行顺序更可控
  4. 等待内部完成:mainFunc中添加await fn(...),确保内部所有异步操作执行完毕

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 16:42:45