NestJS中使用HttpService同时调用多个端点的实现与异常处理方案
实现方案
NestJS的HttpService返回的是RxJS Observable对象,并行调用多个接口可以直接使用RxJS内置的forkJoin操作符实现,以下是完整代码及场景说明:
第一步:导入所需RxJS依赖
import { forkJoin, of, catchError, map } from 'rxjs'; import { AxiosError } from 'axios';
第二步:实现多接口并行调用方法
基础实现(任意请求失败则整体报错)
如果业务要求所有接口都必须成功才能继续逻辑,使用以下写法:
@Injectable() export class AnimalService { constructor(private httpService: HttpService){} // 先修正原有方法的返回类型(你之前map了data,不需要再包裹AxiosResponse) getAnimalData(variant: string): Observable<Animal> { return this.httpService .get<Animal>(`http://animal.test/${variant}`) .pipe(map((response) => response.data)); } getAllAnimalsData(): Observable<Animal[]> { const variants = ['birds', 'cats', 'dogs']; // 生成每个variant对应的请求Observable const requestList = variants.map(variant => this.getAnimalData(variant)); // 并行执行所有请求,全部完成后返回结果数组,顺序和variants顺序一致 return forkJoin(requestList); } }
调用该方法时,返回的数组下标0对应birds的结果,下标1对应cats的结果,下标2对应dogs的结果。你也可以直接传入对象给forkJoin,更方便区分返回值:
getAllAnimalsData(): Observable<{birds: Animal, cats: Animal, dogs: Animal}> { return forkJoin({ birds: this.getAnimalData('birds'), cats: this.getAnimalData('cats'), dogs: this.getAnimalData('dogs') }); }
容忍部分请求失败的实现
如果要保留成功请求的结果,同时标记失败的请求,给每个单独的请求添加catchError处理即可:
// 先定义联合返回类型,方便区分成功和失败的结果 type AnimalResult = { type: 'success', data: Animal } | { type: 'error', variant: string, errMsg: string }; getAllAnimalsData(): Observable<AnimalResult[]> { const variants = ['birds', 'cats', 'dogs']; const requestList = variants.map(variant => this.getAnimalData(variant).pipe( // 请求成功时封装成功标识 map(data => ({ type: 'success', data } as AnimalResult)), // 请求失败时捕获错误,封装错误标识返回,不中断整体流 catchError((err: AxiosError) => of({ type: 'error', variant, errMsg: err.message } as AnimalResult)) ) ); return forkJoin(requestList); }
调用该方法后,你可以遍历返回的数组,通过type字段区分每个请求的状态,分别处理成功和失败的逻辑。
内容的提问来源于stack exchange,提问作者Hary Kamaro
相关产品推荐
相关产品推荐

