如何等待所有异步HTTP请求完成?避免逐个await拖慢执行效率
如何高效发起异步HTTP请求并等待所有结果存入数组?
我需要发起异步HTTP请求并将所有结果存入数组,且必须等待所有请求完成。现有代码如下:
async function(){ const arrayWithResults = []; const urls = ['someurl.com', 'otherurl.com']; urls.map( url => { axios.get(url).then( result => { arrayWithResults.push(result); }); }); }想请教:此处是否只能使用await实现需求?我担忧逐个await会拖慢整体流程。
首先得指出你现有代码的问题:这段代码里,你只是发起了所有请求,但没有等待这些请求完成——函数会直接执行完,而此时axios的请求可能还在进行中,最后arrayWithResults大概率是空的,或者只有部分请求的结果,完全达不到“等待所有请求完成”的要求。
回到你的问题:当然不是只能用逐个await!而且逐个await确实会拖慢流程,因为它是串行执行的——必须等前一个请求完成,才会发起下一个,总耗时是所有请求时间的总和。
要实现并行请求+等待所有完成的需求,最佳方案是用Promise.all(),它能让所有请求同时发起,总耗时等于最慢的那个请求的时间,效率高得多。
修正后的代码如下:
async function fetchAllUrls() { const urls = ['someurl.com', 'otherurl.com']; // 把每个url转换成axios请求的Promise对象,得到一个Promise数组 const promiseArray = urls.map(url => axios.get(url)); // 等待所有Promise完成,直接拿到所有结果组成的数组 const arrayWithResults = await Promise.all(promiseArray); // 这里就可以处理结果数组了 return arrayWithResults; }
解释下这段代码的逻辑:
urls.map(url => axios.get(url))会立刻发起所有HTTP请求,返回一个包含所有请求Promise的数组await Promise.all(promiseArray)会暂停函数执行,直到所有Promise都成功完成,然后把每个Promise的结果按顺序整理成数组返回- 这样你不用手动
push结果,直接就能拿到完整的结果数组,而且所有请求是并行的,不会浪费时间
如果担心某个请求失败导致整个Promise.all()报错,可以用Promise.allSettled()替代,它会等待所有请求完成(不管成功还是失败),返回每个请求的状态和结果,你可以后续自己过滤成功的结果:
async function fetchAllUrlsWithSettled() { const urls = ['someurl.com', 'otherurl.com']; const promiseArray = urls.map(url => axios.get(url)); const results = await Promise.allSettled(promiseArray); // 过滤出成功的结果 const arrayWithResults = results .filter(result => result.status === 'fulfilled') .map(result => result.value); return arrayWithResults; }
总结一下:
- 不要用你原来的写法,因为没有等待请求完成,结果不可控
- 不要用逐个
await的串行方式,效率太低 - 优先用
Promise.all()实现并行请求+等待所有完成的需求,这是最符合你需求的高效方案
内容的提问来源于stack exchange,提问作者Enzo Beltrami
相关产品推荐
相关产品推荐

