如何实现动态请求体的fetch并行发送 等待所有响应后执行后续逻辑
动态并行fetch请求实现方案
你当前的代码是串行发送请求:循环内遇到await fetch就会阻塞后续循环逻辑,必须等上一个请求拿到响应才会构造下一个请求体发下一个请求,执行效率很低。
要实现动态生成请求体+并行发送+所有请求返回后再执行后续逻辑,按下面的步骤修改即可:
- 第一步:先走完所有文件遍历逻辑,按你原来的分批规则(每24个文件/到列表末尾为一批),把每一批对应的请求URL、FormData请求体提前构造好,存入请求配置数组,这一步不发起网络请求
- 第二步:遍历请求配置数组,为每一个配置生成fetch请求的Promise,存入Promise数组
- 第三步:调用
Promise.all()传入Promise数组,会自动并行发起所有请求,等所有请求都返回并解析完JSON后,就能拿到按请求顺序排列的所有结果,之后再执行后续业务逻辑即可
如果你的批次数量特别大(比如超过10个并行请求),担心给后端造成压力,可以加简单的并发控制,限制同时发送的请求数量;批次数量少的话直接用Promise.all就可以。
修改后的参考代码:
// 提前初始化公共变量 const domain = window.location.origin.replace(':8080', ':5000') const requestConfigs = [] let fd = new FormData() let slices = [] let loopcount = 0 // 1. 先构造所有批次的请求配置,不发起网络请求 for (const fileindex of filelist) { let dcmFilename = `slice_${fileindex}.dcm` slices.push({index:fileindex, filename:dcmFilename}) fd.append(dcmFilename, files[fileindex], dcmFilename); fd.append('slices', JSON.stringify(slices)); loopcount += 1 // 满足分批条件时存储当前批次配置 if (filecount == 24 || loopcount == filelist.length){ if (cursorPos !== false) { let scaleFactor = Tegaki.scaleFactor; cursorPos.x = parseInt(cursorPos.x / scaleFactor); cursorPos.y = parseInt(cursorPos.y / scaleFactor); fd.append('x', cursorPos.x); fd.append('y', cursorPos.y) } // 处理每批独立的type、mode参数 let reqType = type let reqMode = mode if (index !== -1) { reqType = this.layerTypes[index]['id'] } if (reqType === 'vertebral-bone' ){ reqMode='PyTorch-Vertebrae' } // 存入配置数组 requestConfigs.push({ url: `${domain}/segment?mode=${reqMode}&type=${reqType}`, body: fd }) // 重置临时变量,准备构造下一批 fd = new FormData() slices = [] } } // 2. 生成所有请求的Promise数组 const fetchPromises = requestConfigs.map(config => { return fetch(config.url, { method: 'POST', body: config.body }).then(res => res.json()) }) // 3. 等待所有并行请求完成,拿到按顺序排列的全部结果 const allResults = await Promise.all(fetchPromises) // 后续业务逻辑直接写在这里即可,allResults数组的顺序和你分批的顺序一一对应 // 例:allResults[0]是第一批请求的返回结果,allResults[1]是第二批的返回结果
注意:如果请求存在失败可能,建议给每个fetch Promise添加catch逻辑,或者用
Promise.allSettled替代Promise.all,避免单个请求失败导致整个流程中断。
内容的提问来源于stack exchange,提问作者Giot Dang
相关产品推荐
相关产品推荐

