Angular中如何每隔30秒轮询后端API直到返回200 OK响应
Angular接口失败后每30秒重试直到返回200实现方案
Angular HTTP请求基于RxJS实现,不需要额外引入第三方依赖,直接通过RxJS操作符即可实现自动重试逻辑,不需要手动维护定时器。
Angular HttpClient默认将所有非2xx状态码的响应判定为错误,触发流的错误通道,我们只需要在错误场景下延迟30秒重新订阅请求流(即重新发起接口调用),直到请求成功进入正常响应通道即可。
基础实现(所有非200响应自动重试)
RxJS 7+ 写法(适配Angular 14及以上版本)
先按需导入需要的RxJS方法:
import { retry } from 'rxjs/operators'; import { timer } from 'rxjs';
替换原有接口调用代码即可:
this.productServices.onProductBuy(product_id) .pipe( // 接口报错时等待30秒自动重试 retry({ delay: () => timer(30 * 1000) }) ) .subscribe(response => { // 仅当接口返回200成功响应时,才会执行此处逻辑 console.log(response); });
旧版本兼容写法(适配Angular 13及以下,RxJS 6.x版本)
import { retryWhen, delay, tap } from 'rxjs/operators'; this.productServices.onProductBuy(product_id) .pipe( retryWhen(errorStream$ => errorStream$.pipe( delay(30 * 1000), // 可选:打印重试日志方便调试 tap(err => console.warn('接口未返回200状态,30秒后将自动重试', err)) )) ) .subscribe(response => { console.log(response); });
扩展:按错误类型选择性重试
如果后续需要调整规则,比如400参数错误、401未授权、403权限不足这类客户端问题不需要重试,只有服务端异常、网络错误才重试,可以在重试逻辑中增加判断,不符合重试条件的错误直接抛出终止流即可:
import { retry, mergeMap } from 'rxjs/operators'; import { timer, throwError } from 'rxjs'; this.productServices.onProductBuy(product_id) .pipe( retry({ delay: (err) => { // 4xx客户端错误直接抛出,不触发重试 if (err.status >= 400 && err.status < 500) { return throwError(() => err); } // 其余错误等待30秒后重试 return timer(30 * 1000); } }) ) .subscribe({ next: response => console.log('请求成功', response), error: err => console.log('请求终止,不再重试', err) });
注意事项
- 不要手动用
setInterval实现重试逻辑:RxJS的重试操作符会自动托管订阅生命周期,组件销毁时只要按照常规Angular写法取消订阅(比如用takeUntil触发流销毁、或者用async管道接管订阅),不会出现内存泄漏、页面销毁后仍发请求的问题。 - 如果你的
onProductBuy封装方法内部写了catchError错误处理,不要吞掉原始错误,需要将错误重新向下抛,否则外层的重试逻辑无法感知错误,不会触发重试。
内容的提问来源于stack exchange,提问作者ilikechocolate
相关产品推荐
相关产品推荐

