我有一个简单的请求,如果状态为 202 ,我想重复一下。目前,它看起来像这样:
this.http.get(endPoint, {
withCredentials: true,
headers: this.headers
})
.map((response: Response) => {
return response.text() ? response.json() : '';
})
.catch((error) => this.handleError(error));
我尝试使用.repeatWhen()
,但不幸的是,我没有收到Response
对象,我无法通过状态代码设置验证。
任何想法我该怎么做?
答案 0 :(得分:2)
这是对repeatWhen()
如何运作的误解。对此运算符的回调接收单个参数,该参数是一个Observable,它在源完成时推送空项。所以它对你来说并不理想(因为你无法访问所需的Response对象)。
您可以改为使用retryWhen()
:
this.http.get(endPoint, { withCredentials: true, headers: this.headers })
.map((response: Response) => {
if (response.code === 202) {
throw response;
}
return response;
})
.map((response: Response) => {
return response.text() ? response.json() : '';
})
.retryWhen(obs => {
return obs; // always just resubscribe without any further logic
});
这会将response
作为错误抛出,然后由retryWhen
捕获,只会重新订阅。如果您重新订阅,您当然可以使用更多逻辑来控制,例如:
.retryWhen(obs => {
return obs.filter(...);
});
答案 1 :(得分:0)
您可以在捕获方法
中再次进行http调用.catch(res => {
return res.status === 202?
this.http.get(endPoint):
Observable.throw(res);
});
答案 2 :(得分:0)
如何使用flatMap:
.flatMap((response:Response) => {
if (response.status === 200) {
return Observable.of(this.mapResponse(response.json()));
} else if (response.status === 202) {
return this.http.get(endPoint, {
withCredentials: true,
headers: this.headers
});
}
})
答案 3 :(得分:0)
将其用于Rx6。这将重试202次最多3次,并在第三次尝试结束时引发超时错误。
@Injectable()
export class ProgressInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
map(t => {
if (t['status'] === 202) {
throw 202;
}
return t;
}),
retryWhen(t => {
return t.pipe(
concatMap((e, i) => {
if (e !== 202) {
return throwError(e);
}
return iif(
() => i >= 2,
throwError(new Error('Operation Timed Out!')),
of(e).pipe(delay(1000))
)
})
)
}),
);
}
}