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

使用Axios循环请求服务端数据并按调用顺序存入数组的实现问题

问题说明

需求为在循环逻辑中从服务端拉取数据,严格按照请求发起的顺序将响应结果存入数组。此前先后尝试递归、Promise、async/await、同步请求等多种实现方案,累计调整7版代码,均未实现按顺序存储响应的效果,当前基于Axios编写的递归实现代码如下:

let currentPhraseWordAssign = [];

function addPartOfSpeechAndWordPhrasesToFullScript () {
    assignPartOfSpeechAndAddToPhraseArray(["phrase", "run"]).then(() => {console.log(currentPhraseWordAssign)});
}


async function assignPartOfSpeechAndAddToPhraseArray (phrase) {
    if(currentPhraseWordAssign.length >= phrase.length) {
        console.log(currentPhraseWordAssign);
        currentPhraseWordAssign = [];
        return;
    }
    let word = phrase[currentPhraseWordAssign.length];
    axios({
        method: 'get',
        url: `http://localhost:9200/english_minus_verbs/_search`,
        headers: {
            'Content-Type': 'application/json'
        },
        data: {
            _source: ["part_of_speech"],
            query: {
                term: {
                    word: word,
                }
            }
        }
    }).then((r) => {
        try {
            currentPhraseWordAssign.push({word: word, partOfSpeech: r.data.hits.hits[0]._source.part_of_speech});
        }catch (e) {
            currentPhraseWordAssign.push({word: word, partOfSpeech: 'verb'});
        }
    }).then(()=>{
        assignPartOfSpeechAndAddToPhraseArray(phrase);
    });
}
现有代码逻辑问题
  • 标记为async的函数内部没有对axios异步请求做await或返回Promise实例,外层调用的.then会在函数刚启动、第一个请求还没返回时就触发,此时结果数组还未填充完成,打印时机完全错误。
  • 结果存在全局变量currentPhraseWordAssign中,多次触发函数时会出现数据互相污染的问题,且递归终止时直接清空全局数组,外层拿到的引用会指向空数组。
  • 没有对axios请求本身做异常捕获,单个请求报错会直接打断整个递归链,没有兜底处理。
修复方案

要严格保证结果顺序和请求发起顺序一致,有两种可落地的实现:

方案1:串行请求(逻辑最直观)

等上一个请求拿到结果存入数组后,再发起下一个请求,全程用async/await控制异步流程,不依赖全局变量存结果。

async function assignPartOfSpeechAndAddToPhraseArray(phrase) {
  const result = [];
  for (const word of phrase) {
    try {
      const r = await axios({
        method: 'get',
        url: `http://localhost:9200/english_minus_verbs/_search`,
        headers: {
          'Content-Type': 'application/json'
        },
        data: {
          _source: ["part_of_speech"],
          query: { term: { word } }
        }
      });
      result.push({
        word,
        partOfSpeech: r.data.hits.hits[0]._source.part_of_speech
      });
    } catch (e) {
      // 接口报错、返回结构不符合预期都走兜底逻辑
      result.push({
        word,
        partOfSpeech: 'verb'
      });
    }
  }
  return result;
}

function addPartOfSpeechAndWordPhrasesToFullScript() {
  assignPartOfSpeechAndAddToPhraseArray(["phrase", "run"]).then(res => {
    console.log(res); // 拿到的结果严格和输入词顺序一致
  });
}

方案2:并行请求(性能更高)

同时发起所有请求,通过Promise.all等待所有请求返回,Promise.all返回的结果顺序和传入的Promise数组顺序严格一致,完全满足顺序要求,请求耗时为所有请求中最长的单个请求耗时,比串行方案快很多。

async function assignPartOfSpeechAndAddToPhraseArrayParallel(phrase) {
  const requestPromises = phrase.map(async (word) => {
    try {
      const r = await axios({
        method: 'get',
        url: `http://localhost:9200/english_minus_verbs/_search`,
        headers: {
          'Content-Type': 'application/json'
        },
        data: {
          _source: ["part_of_speech"],
          query: { term: { word } }
        }
      });
      return { word, partOfSpeech: r.data.hits.hits[0]._source.part_of_speech };
    } catch (e) {
      return { word, partOfSpeech: 'verb' };
    }
  });
  return Promise.all(requestPromises);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:30:58