すべてのhttpリクエストはカスタムHttpServiceを経由します。このサービスは、要求を送信する前にトークンが期限切れになったときにそのトークンをリフレッシュします。Angularは非同期リクエストで複数のトークンリフレッシュを防止します
正常に動作しますが、ロードされたページに複数の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
.....
}
}
私はpereventすることができますどのようにこれらのリクエストを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 }
私はこれもキャストする必要があると思いますか?
初めての複数の並列呼び出しを持っていません
' Promise'と 'Observable'の間の適切なキャスティングによってこれらのエラーを取り除くことができたが、今度は別のエラーが出る。 –