如何用Rxjs实现带不同请求头的多次轮询及重试请求功能?
正确实现代码
public getProfitability(): Observable<Profitability> { // 封装通用请求方法,入参控制是否携带pullingOk特殊头 const sendRequest = (isLastPull: boolean = false) => { let headers = this.configService.concatenateHeaders(); if (isLastPull) { // 追加pullingOk请求头,可根据你的configService方法调整写法 headers = headers.append('pullingOk', 'true'); // 如果你要使用已有的paramOk方法可以直接替换:headers = this.configService.paramOk() } return this.http.get<Profitability>( this.configService.generateNewUrl(`${environment.api.newEndpoints.profitability}`), { headers } ).pipe( // 单请求失败最多重试3次,符合需求 retry({ count: 3, delay: 500, tap: () => console.log("error occurred getProfitability() ") }) ); }; return sendRequest().pipe( concatMap(firstRes => { // 不符合轮询条件直接返回首次请求结果 if (!firstRes.hasProcessado) { return of(firstRes); } // 符合条件发起10次轮询 return interval(500).pipe( take(10), // 索引为9时对应第10次轮询,传入标识携带特殊头 concatMap(index => sendRequest(index === 9)), tap(result => console.log(result)), // 取最后一次轮询结果返回 last() ); }), shareReplay(1) ); }
核心改动说明
- 封装独立的
sendRequest请求方法,通过入参控制是否追加pullingOk: true请求头,避免重复编写请求逻辑 - 重试逻辑放到单请求内部,确保每一次接口调用失败都最多重试3次,符合需求
- 通过
interval发出的索引判断轮询次数,索引为9时对应第10次请求,触发特殊头携带逻辑 - 修复原代码复用同一个请求Observable,无法动态修改请求参数的问题
- 调整
last()算子的位置,避免不需要轮询的场景下抛出空序列异常
内容的提问来源于stack exchange,提问作者Guilherme Lucas
相关产品推荐
相关产品推荐

