それで、私はこの問題の解決策を得ようとしていました。しかし、どういうわけか私はそうすることができません。angular 5.の知識が不足しているためかもしれません。これは私のサービスです:
GetCurrentUserData(): Observable<ResponseData> {
return this.http.get<ResponseData>(ApplicationURLS.GetCurrentUserInformation)
.map(response => {
return response;
});
//.catch(error => this.handleError(error));
}
これは私のコンポーネントです:
public GetCurrentUserInformation(): any {
return this.loginService.GetCurrentUserData().subscribe(data => { return data; });
}
ここで私はデータにアクセスしようとしています:
ngAfterViewInit() {
debugger;
this.responseData = this.GetCurrentUserInformation();
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
}
This.responseDataを確認すると、常にデータが必要なので、これを返します。
データをすぐに取得できるように、同期呼び出しを行いたいだけです。
また、サービスでdo()を使用しようとしましたが、戻りのdo()は関数ではありません。
これはasync/await
????????
public GetCurrentUserInformation(): Promise<any>{
return this.loginService.GetCurrentUserData().toPromise()
}
ngAfterViewInit
async ngAfterViewInit() {
this.responseData = await this.GetCurrentUserInformation(); // ????♂️
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
}
GetCurrentUserData()
にサブスクライブします。http呼び出しは非同期です(すべてのブラウザーAPI呼び出しは非同期です。これは、JavaScriptエンジンが単一のスレッドで実行されるためです(ブラウザーイベントループの場合はgoogle、これはangular問題))
this.GetCurrentUserInformation().subscribe((data: ResponseData) => {
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
});
非同期関数は非同期であるため、同期的に呼び出すことはできません。
subscribe
は通常、連鎖が予想されるメソッドでは実行しないでください。必要な場合でも、サブスクリプションではなくオブザーバブルをメソッドから返す必要があります(サブスクリプションは、破棄時にサブスクライブを解除するために追加で保存できます)。
GetCurrentUserInformation
メソッドはサービス呼び出しの単なるラッパーなので、冗長です。コードは次のようにリファクタリングできます。
ngAfterViewInit() {
this.loginService.GetCurrentUserData().subscribe(data => {
this.responseData = data;
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
});
}
応答を処理する前に非同期呼び出しが確実に実行されるようにするには、ReactiveXのObservable.forkJoin()を使用できます。
Observable.forkJoin(
this.http.get('/links.json').map((response:Response) => response.json()),
this.http.get('/bookmarks.json').map((response:Response) => response.json())
).subscribe(
data => {
this.links = data[0]
this.bookmarks = data[1]
},
error => console.error(error)
);
subscribe()関数のonNextハンドラは、すべてのHTTPリクエストが正常に完了すると実行されます。
必要なインポート:
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
詳細は この記事 をご覧ください。
同期呼び出しを直接行う方法はありませんが、次の手順を実行できます(このコードはangular 7)で記述されています)。
import { Component, OnInit } from '@angular/core';
import {HttpClient} from '@angular/common/http';
export class SampleComponent implements OnInit {
Request1result:Object;
Request2result:Object;
constructor(private http:HttpClient) { }
ngOnInit()
{
this.http.get("URL1").subscribe((res)=>{
this.Request1result=res;
this.after1(); // execution will move to next request only when first is done.
});
}
after1()
{
this.http.get("URL2").subscribe((res)=>{
this.Request2result=res;
this.after2(); // execution will move to the rest of the code only when both the requests are done.
});
}
after2()
{
// rest of the code.
console.log(this.Request1result);
console.log(this.Request2result);
}
}