Angular如何实现分批并发调用地址校验API
控制API并发分批校验地址实现方案
完全可以在Angular端手动控制API调用并发数,按固定批次串行执行的方案可以直接解决当前请求无响应的问题。
你当前的实现问题在于:普通for循环遍历发起异步请求时,不会等待上一个请求返回就会直接发起下一个,短时间内把1500个请求全打出去,要么触发浏览器同域名并发连接数限制(Chrome同域名HTTP/1.1并发上限一般是6个,多的请求会排队甚至超时),要么触发后端接口的限流规则,才会出现只能成功40-50个请求的情况。
- 首先实现数组拆分工具方法,把全量地址按你设定的单批大小拆成多个小数组
// 通用数组分块方法 chunkArray<T>(data: T[], chunkSize: number): T[][] { const chunks: T[][] = []; for (let i = 0; i < data.length; i += chunkSize) { chunks.push(data.slice(i, i + chunkSize)); } return chunks; }
- 基于RxJS实现串行分批请求逻辑,Angular自带RxJS依赖,不需要额外安装包。核心逻辑是用
concatMap保证前一批所有请求全部返回后,才会发起下一批请求,单批内部用forkJoin实现固定数量的并发调用。
把以下逻辑绑定到「VERIFY ALL」按钮的点击事件即可:
import { from, forkJoin, concatMap, map, catchError, of } from 'rxjs'; // 全量校验触发方法 onVerifyAllClick() { // 单批并发数,可根据接口实际表现调整 const CONCURRENT_LIMIT = 10; const addressChunks = this.chunkArray(this.addresses, CONCURRENT_LIMIT); from(addressChunks) .pipe( concatMap(chunk => { // 组装当前批次的所有校验请求 const requests = chunk.map(addr => this.addressService.verify(addr).pipe( // 单条请求失败不中断整批流程,标记为校验失败即可 catchError(() => of(false)), map(validResult => ({ addr, valid: validResult })) ) ); // 等待当前批次所有请求完成后再进入下一批 return forkJoin(requests); }) ) .subscribe({ next: (batchResult) => { // 每批校验完成后实时更新表格数据,用户可即时看到结果 batchResult.forEach(res => { const target = this.addresses.find(item => item.address === res.addr.address && item.zip === res.addr.zip ); if (target) target.verifyResult = res.valid; }); }, complete: () => { // 全量校验完成后的逻辑,比如弹出成功提示 console.log('所有地址校验完成'); } }); } // 地址服务类中的API调用方法,替换成你自己的接口路径即可 verify(address): Observable<boolean> { return this.http.post<boolean>('/api/address/verify', address); }
几个落地的实用提示:
- 单批大小不用固定为10,可以先从10开始测,如果接口稳定无报错,可以逐步调到15、20,缩短整体校验耗时
- 单条接口报错一定要捕获,不要让错误冒泡打断整个批量校验流程
- 如果需要支持中途停止校验,只要保存subscribe返回的Subscription实例,调用
unsubscribe()方法即可终止后续批次的请求- 不要用
async/await加普通for循环实现单条串行(即一次只发1个请求等返回再发下一个),这种方式总耗时太长,1500条数据会等很久,固定批次并发的方式效率高很多
内容的提问来源于stack exchange,提问作者Danielle
相关产品推荐
相关产品推荐

