Angular 4:如何批量执行同步HTTP请求
在Angular 4中实现串行HTTP PUT请求
我完全理解你的痛点——一次性发起上千个请求确实很容易把后端打崩,尤其是后端没做限流的时候。在Angular 4(搭配RxJS 5.x)里,我们可以利用RxJS的操作符轻松把并行请求改成串行执行,让每个PUT请求都等前一个完成后再发起。
先看你可能的原有实现(并行问题版本)
估计你之前的代码大概是这样的,直接遍历数组并逐个订阅请求,导致所有请求同时发起:
// 假设这是你的上传数据数组 const uploadData: any[] = [...]; uploadData.forEach(item => { this.http.put(`/api/items/${item.id}`, item) .subscribe( res => console.log(`Item ${item.id} uploaded`), err => console.error(`Failed to upload ${item.id}`, err) ); });
这种写法在数据量小的时候没问题,但数据量大就会导致后端连接数过载。
解决方案1:使用from + concatMap(最简洁的方式)
RxJS的from可以把数组转换成一个Observable序列,每次发射一个数组元素;而concatMap会等待前一个请求的Observable完成后,再处理下一个元素并发起新的请求,完美实现串行执行:
import { from } from 'rxjs'; import { concatMap } from 'rxjs/operators'; // 你的上传方法 uploadItemsSerial(uploadData: any[]) { return from(uploadData).pipe( concatMap(item => { // 这里返回每个PUT请求的Observable return this.http.put(`/api/items/${item.id}`, item); }) ); } // 调用这个方法 this.uploadItemsSerial(yourDataArray) .subscribe( res => console.log('单个请求完成', res), err => console.error('请求出错', err), () => console.log('所有上传请求已完成!') );
解决方案2:使用reduce手动串联Observable
如果你想更手动地控制串联过程,可以用reduce操作符把所有请求Observable逐个串联起来:
import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/of'; import 'rxjs/add/operator/concat'; uploadItemsSerial(uploadData: any[]) { return uploadData.reduce((prevObs, item) => { return prevObs.concat( this.http.put(`/api/items/${item.id}`, item) ); }, Observable.of(null)); // 初始值是一个空的Observable } // 调用方式和上面一样 this.uploadItemsSerial(yourDataArray) .subscribe(/* ... */);
额外:错误处理的小提示
如果某个请求失败了,默认情况下整个串行流会停止。如果你希望即使某个请求失败,后续请求依然继续执行,可以在concatMap里加入catchError:
import { from } from 'rxjs'; import { concatMap, catchError } from 'rxjs/operators'; import { of } from 'rxjs/observable/of'; uploadItemsSerial(uploadData: any[]) { return from(uploadData).pipe( concatMap(item => { return this.http.put(`/api/items/${item.id}`, item).pipe( catchError(err => { console.error(`上传${item.id}失败`, err); return of(null); // 返回一个空的Observable,让流继续 }) ); }) ); }
这样即使某个请求失败,后续的上传任务依然会继续执行,不会中断整个流程。
内容的提问来源于stack exchange,提问作者user3412296
相关产品推荐
相关产品推荐

