使用RxJS retry操作符时如何处理错误(不使用retryWhen)
问题翻译
我有一段用于请求数据的RxJS代码,希望请求失败时以固定延迟无限重试,目前通过retry操作符实现该逻辑。但我想在请求失败时处理错误(更新组件中的变量)。尝试按照文章示例订阅retry操作符时,出现TS2339: Property 'subscribe' does not exist on type 'MonoTypeOperatorFunction'错误。请问不使用已废弃的retryWhen,是否有办法通过retry操作符处理错误?代码如下:
const interval = 2000; this.xyzService.getData() .pipe( takeUntil(this.destroy$), retry({ delay: interval, resetOnSuccess: true }), //catchError(() => { // ...handling error... // return EMPTY; //}), map((response) => { this.data = response.body; this.state = 'LOADED'; }), delay(interval), repeat(), ).subscribe()
解决方案
你可以利用retry操作符的delay配置项支持函数形式的特性,在延迟函数里处理错误逻辑,同时不中断重试流程。
修改后的代码如下:
const interval = 2000; this.xyzService.getData() .pipe( takeUntil(this.destroy$), retry({ delay: (error) => { // 在这里处理错误:更新组件变量 this.state = 'ERROR'; console.error('请求失败,即将重试:', error); // 返回延迟的Observable,实现固定间隔重试 return timer(interval); }, resetOnSuccess: true }), map((response) => { this.data = response.body; this.state = 'LOADED'; }), delay(interval), repeat() ).subscribe();
关键说明
retry的delay参数不仅可以传数字,还能传一个接收error参数的函数,返回一个Observable(比如timer)。这个函数会在每次请求失败时触发,刚好用来处理错误状态更新。- 不要用
catchError直接吞掉错误,那样会终止整个流,retry就不会生效了。用delay函数处理错误,既完成了状态更新,又能让retry继续执行重试逻辑。 - 你之前遇到的
TS2339错误,应该是尝试直接订阅retry操作符本身(而不是管道后的Observable)导致的,确保订阅的是整个pipe链返回的Observable即可。
额外优化
如果不需要每次成功后再延迟重复请求(原代码里的delay(interval) + repeat()),其实retry已经能处理失败重试,成功后直接更新状态就行,多余的delay+repeat可以去掉,避免不必要的重复请求:
const interval = 2000; this.xyzService.getData() .pipe( takeUntil(this.destroy$), retry({ delay: (error) => { this.state = 'ERROR'; console.error('请求失败,即将重试:', error); return timer(interval); }, resetOnSuccess: true }), map((response) => { this.data = response.body; this.state = 'LOADED'; }) ).subscribe();
内容的提问来源于stack exchange,提问作者greenbanzai
相关产品推荐
相关产品推荐

