关于使用await Promise.all与axios实现并发请求的疑问
Promise.all搭配axios实现并发请求的疑问解答
需求与代码示例
需要用await Promise.all配合axios实现请求并发,输入是一个以id为键、url为值的Map,输出要保持相同键结构,值为请求返回的ArrayBuffer响应内容。
大语言模型给出的代码示例:
async function fetchImages( idUrlMap: Map<string, string> ): Promise<Map<string, ArrayBuffer>> { // Convert the map into an array of promises const promises = Array.from(idUrlMap.entries()).map(([id, url]) => { return axios .get(url, { responseType: 'arraybuffer' }) .then(response => ({ id, data: response.data })); }); // Resolve all promises concurrently const results = await Promise.all(promises); // Convert the results back into a map const resultMap = new Map<string, ArrayBuffer>(); results.forEach(({ id, data }) => { resultMap.set(id, data); }); return resultMap; }
用户疑问
对每个数组元素调用axios.get().then(),会让每个promise准备好就立即resolve,那么这些promise不会被聚合到Promise.all处统一resolve,这样就无法实现并发了。这个理解是否正确?为什么?
解答
你的理解是错误的,核心原因如下:
- 请求在调用axios.get()时就已并发发起:当遍历
idUrlMap生成promises数组的过程中,每执行一次axios.get(),就已经向目标URL发送了HTTP请求。这些请求是同时启动的,属于并发执行,完全不需要等到Promise.all调用才开始。 - .then()仅做结果格式转换,不影响并发逻辑:
.then(response => ({ id, data: response.data }))只是给每个axios返回的Promise绑定了一个回调函数,当对应的请求完成、Promise resolve时,这个回调会把响应数据和对应的id打包成对象。这个操作不会改变Promise的并发执行状态,只是修改了最终resolve的值格式,方便后续转换成Map。 - Promise.all的作用是统一等待与结果汇总:
Promise.all(promises)的核心作用是等待传入的所有Promise都完成(不管它们完成的先后顺序),然后把所有Promise的resolve结果按数组顺序收集起来返回。它并不控制请求的启动时机,只是做结果的统一等待和汇总。
综上,这段代码的并发逻辑是完全成立的,所有请求在生成promises数组的阶段就已经并发发起,Promise.all只是等待所有请求结束后统一处理结果。
内容的提问来源于stack exchange,提问作者10may
相关产品推荐
相关产品推荐

