如何使用rxjs重试并在此之后执行函数



我想重试一个api调用10次(等待一秒钟,因为它失败了,直到下一次执行(,如果这10次失败,那么我将执行一个函数,这是我的方法:

private handleError(error, req: HttpRequest<any>, next: HttpHandler): Observable<any> {
if (error.status === 0) {
return next.handle(req).pipe(
catchError(err => timer(1000).pipe(switchMapTo(this.checkConnection(err)))),
retry(10)
);
} 
}
private checkConnection(error): Observable<any> {
console.log(error)      
return EMPTY;
}

这不起作用,通过使用提供的关于在重试和捕获错误之间切换顺序的解决方案,计时器停止工作。

我也尝试过重试当:

if (error.status === 0) {
return next.handle(req).pipe(
retryWhen(errors => errors.pipe(delay(1000), take(10), 
concatMapTo(this.checkConnection(errors)))));
}

然后我的问题只重试了一次,我的"中没有原始错误;checkConnection";功能

通过使用控制台日志,我可以看到这是任何尝试都会执行的,我想得到的是一旦执行了10次就执行。

我不知道怎么做。

我用的是角度8。

根据提供的答案,我的代码应该可以工作,但它没有,它有一个编译错误,这是我的全部服务:

import { throwError,  Observable , EMPTY } from 'rxjs';
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { catchError, delay, retryWhen, take, concatMap } from 'rxjs/operators';
import { Router } from '@angular/router';

@Injectable()
export class HttpErrorInterceptorService implements HttpInterceptor {
private handleError(error, req: HttpRequest<any>, next: HttpHandler): Observable<any> {
if (error.status === 401) {
this.router.navigate(['/login']);
return EMPTY;  // Stops processing
} else if (error.status === 403) {
this.router.navigate(['/unauthorized']);
return EMPTY;  // Stops processing
}  else if (error.status === 0) {
return next.handle(req).pipe(
retryWhen((errors) => {
return errors.pipe(
delay(1000),
take(10), // Number of retries
concatMap(throwError)// Let the error bubble up again
);
}),
catchError((err) => this.checkConnection(err)));
}
return throwError(error);
}
private checkConnection(error): Observable<any> {
//it will have more logic in future, this is just the starting point to this function
console.log(error)      
return EMPTY;
}
constructor(private router: Router) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((error) => this.handleError(error, req, next))
);
}

}

编译错误为

类型为"的参数(错误:any,scheduler?:SchedulerLike(=>Observable"不可分配给类型为"的参数(值:any,索引:number(=>可观察"。参数"scheduler"one_answers"index"的类型不兼容。类型"number"不可分配给类型"SchedulerLike"。

retry应该正好捕获内部错误N次。第N+1次,它将按预期进行。目前,您可以捕获每个错误,并通过管道将其发送到checkConnection。基本上,在原始示例中切换retrycatchError应该已经完成了这项工作。

import {Observable, throwError, EMPTY} from 'rxjs';
import {concatMap, delay, retryWhen, take} from 'rxjs/operators';
private handleError(error, req: HttpRequest<any>, next: HttpHandler): Observable<any> {
if (error.status === 0) {
return next.handle(req).pipe(
retryWhen((errors) => {
return errors.pipe(
delay(1000),
take(10), // Number of retries
concatMap(throwError), // Let the error bubble up again
)
),
catchError((err) => this.checkConnection(err))),
);
} 
}
private checkConnection(error): Observable<any> {
console.log(error)      
return EMPTY;
}

你好像掉进了兔子洞。你可以尝试使用repeat操作符,因为它的设计目的正是为了做你正在尝试的事情。


// RxJS v6+
import { repeat, delay } from 'rxjs/operators';
const delayedThing = yourObservable.pipe(delay(2000));
delayedThing
.pipe(repeat(3))
// delayed value...delayed value...delayed value
.subscribe(console.log);

最新更新