我的所有http请求都会通过自定义 HttpService 。此服务在发送请求之前刷新令牌。
它工作正常,但如果加载的页面有多个http请求,它会多次刷新令牌。例如,如果页面通过服务有10个请求,则表示令牌刷新10次。
我试图通过示例代码来描述这个:
已加载的页面和已使用的服务
export class Page1 implements OnInit {
constructor(
private service1: Service1,
private service2: Service2
) { }
ngOnInit() {
this.service1.getData...
this.service2.getData...
}
}
@Injectable()
export class Service1 {
constructor(
private httpService: HttpService
) {}
getData(): Observable<any> {
return this.httpService.get(.....)
.map((response: Response) => {
return response.json();
});
}
}
@Injectable()
export class Service2 {
constructor(
private httpService: HttpService,
private service1: Service1
) {}
getData(): Observable<any> {
return this.httpService.get(.....)
.map((res: Response) => res.json().response)
.flatMap((newItem: Item) => {
this.service1.getData(...)
});
}
}
自定义http服务
@Injectable()
export class HttpService extends Http {
constructor (backend: XHRBackend, options: RequestOptions) {
.............
}
request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
................
if(tokenNotExpired('access_token')){ // if token is NOT expired
return super.request(url, options);
}else{ // if token is expired
return this.updateToken()
.flatMap((result: boolean) => {
return this.request(url, options);
});
}
}
updateToken(): Observable<boolean> {
// set the new token
.....
}
}
如何通过在que中设置这些请求来保留每个请求的令牌刷新,并仅在新令牌准备就绪时发送它们?
注意:我不知道是否有问题,但服务请求可以由flatMap
或forkJoin
.... <组合/ p>
更新1
我已根据 @bviale 的答案更新了我的代码。
request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
................
if(tokenNotExpired('access_token')){ // if token is NOT expired
return super.request(url, options);
} else { // if token is expired
// There is already a call to updateToken() in progress,
// wait for it to finish then process the request
if (this.updateTokenPromise) {
return Observable.fromPromise(return this.updateTokenPromise.then(() => {
return this.request(url, options);
}));
}
// Start to call updateToken(), then resolve the promise
else {
this.updateTokenPromise = new Promise((resolve, reject) => {
this.updateToken().toPromise()
.then((result: boolean) => {
resolve(result);
});
});
return Observable.fromPromise(return this.updateTokenPromise.then(() => {
return this.request(url, options);
}));
}
}
}
我更新的request()
方法完全停止请求,只调用updateToken()
一次,获取令牌,然后调用请求但是对于每个请求,我现在收到以下错误:
我注意到服务调用会返回以下响应,其中会导致e.json is not a function
异常:
Object { _isScalar: false, source: Object, operator: Object }
我认为这也是我需要施展的东西吗?
答案 0 :(得分:0)
当您像这样致电updateToken()
时,您可以创建自己的承诺:
@Injectable()
export class HttpService extends Http {
private updateTokenPromise: Promise<any>;
constructor (backend: XHRBackend, options: RequestOptions) {
.............
}
request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
................
if(tokenNotExpired('access_token')){ // if token is NOT expired
return super.request(url, options);
} else { // if token is expired
// There is already a call to updateToken() in progress,
// wait for it to finish then process the request
if (this.updateTokenPromise) {
return this.updateTokenPromise.then(() => {
return this.request(url, options);
});
}
// Start to call updateToken(), then resolve the promise
else {
this.updateTokenPromise = new Promise((resolve, reject) => {
this.updateToken()
.then((result: boolean) => {
resolve(result);
});
});
return this.updateTokenPromise.then(() => {
return this.request(url, options);
});
}
}
}
updateToken(): Observable<boolean> {
// set the new token
.....
}
}
这样您就不会有updateToken()