[英]Angular prevent multiple token refresh on asynchronous requests
我所有的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
...組合。
更新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 }
我認為這也是我需要投射的東西嗎?
您可以像這樣調用updateToken()
來創建自己的Promise:
@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()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.