HTTP请求使用拦截器重试特定错误并重试
HTTP Request retry on particular error using interceptor and retrywhen
我有一项服务可以调用 GET API 并收到回复。我已经实现了 HTTP 拦截器来正确地全局处理应用程序中的任何错误。我想做的是,当我的 API returns 出现特定错误时,例如错误 501,我需要在每次请求之前重试该请求 n 次和延迟 t 秒。如果我的重试结束,我还想处理一般错误(即,如果我在上次重试时出错,我想以特定方式处理它)。请帮我弄清楚如何解决这个问题。
这都是使用Angular6实现的,语法正确的解决方案将不胜感激。
谢谢
你可以考虑使用 RxJS 的 retryWhen
、delay
、tap
、scan
。类似于下面的代码,其中 Angular 服务调用 Google API 来验证浏览器上没有 运行 的应用程序中的用户,例如一个桌面应用程序。此服务使用 RxJS 在特定时间间隔重试 REST API 调用,以防因互联网连接不稳定而失败:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { retryWhen, delay, tap, scan, concatMap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class GoogleDeviceAuthService {
private readonly client_id = "<client-id>";
private readonly client_secret = "<client-secret>";
private readonly userCodeRequest = {
"client_id": this.client_id,
"scope": "email profile"
};
private readonly pollGoogleAuthServerRequestTemplate = {
"client_id": this.client_id,
"client_secret": this.client_secret,
"code": "",
"grant_type": "http://oauth.net/grant_type/device/1.0"
}
private readonly userCodeUrl = "https://accounts.google.com/o/oauth2/device/code";
private readonly pollGoogleAuthServerUrl = "https://www.googleapis.com/oauth2/v4/token";
constructor(private readonly http: HttpClient) { }
public getUserCode() {
return this.http.post(this.userCodeUrl, this.userCodeRequest)
.pipe(
retryWhen(err => err.pipe(
scan(
(retryCount, err) => {
if (retryCount > 3)
throw err;
else
return retryCount + 1;
}, 0
),
delay(1000),
tap(err => console.log("Retrying...", err))
)));
}
public checkAuthServerForUserInput(deviceCode) {
let pollGoogleAuthServerRequest = {
...this.pollGoogleAuthServerRequestTemplate,
...{ "code": deviceCode } };
return this.http.post(this.pollGoogleAuthServerUrl, pollGoogleAuthServerRequest)
.pipe(
retryWhen(err => err.pipe(
scan(
(retryCount, err) => {
if (retryCount > 3)
throw err;
else
return retryCount + 1;
}, 0
),
delay(1000),
tap(err => console.log("Retrying...", err))
)));;
}
}
我有一项服务可以调用 GET API 并收到回复。我已经实现了 HTTP 拦截器来正确地全局处理应用程序中的任何错误。我想做的是,当我的 API returns 出现特定错误时,例如错误 501,我需要在每次请求之前重试该请求 n 次和延迟 t 秒。如果我的重试结束,我还想处理一般错误(即,如果我在上次重试时出错,我想以特定方式处理它)。请帮我弄清楚如何解决这个问题。
这都是使用Angular6实现的,语法正确的解决方案将不胜感激。
谢谢
你可以考虑使用 RxJS 的 retryWhen
、delay
、tap
、scan
。类似于下面的代码,其中 Angular 服务调用 Google API 来验证浏览器上没有 运行 的应用程序中的用户,例如一个桌面应用程序。此服务使用 RxJS 在特定时间间隔重试 REST API 调用,以防因互联网连接不稳定而失败:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { retryWhen, delay, tap, scan, concatMap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class GoogleDeviceAuthService {
private readonly client_id = "<client-id>";
private readonly client_secret = "<client-secret>";
private readonly userCodeRequest = {
"client_id": this.client_id,
"scope": "email profile"
};
private readonly pollGoogleAuthServerRequestTemplate = {
"client_id": this.client_id,
"client_secret": this.client_secret,
"code": "",
"grant_type": "http://oauth.net/grant_type/device/1.0"
}
private readonly userCodeUrl = "https://accounts.google.com/o/oauth2/device/code";
private readonly pollGoogleAuthServerUrl = "https://www.googleapis.com/oauth2/v4/token";
constructor(private readonly http: HttpClient) { }
public getUserCode() {
return this.http.post(this.userCodeUrl, this.userCodeRequest)
.pipe(
retryWhen(err => err.pipe(
scan(
(retryCount, err) => {
if (retryCount > 3)
throw err;
else
return retryCount + 1;
}, 0
),
delay(1000),
tap(err => console.log("Retrying...", err))
)));
}
public checkAuthServerForUserInput(deviceCode) {
let pollGoogleAuthServerRequest = {
...this.pollGoogleAuthServerRequestTemplate,
...{ "code": deviceCode } };
return this.http.post(this.pollGoogleAuthServerUrl, pollGoogleAuthServerRequest)
.pipe(
retryWhen(err => err.pipe(
scan(
(retryCount, err) => {
if (retryCount > 3)
throw err;
else
return retryCount + 1;
}, 0
),
delay(1000),
tap(err => console.log("Retrying...", err))
)));;
}
}