问题
So, I was trying to get the solution of this problem. But, somehow I am unable to do so, May be because of the lack of knowledge in angular 5. This is my service:
GetCurrentUserData(): Observable<ResponseData> {
return this.http.get<ResponseData>(ApplicationURLS.GetCurrentUserInformation)
.map(response => {
return response;
});
//.catch(error => this.handleError(error));
}
This is my component:
public GetCurrentUserInformation(): any {
return this.loginService.GetCurrentUserData().subscribe(data => { return data; });
}
Here I am trying to access the data:
ngAfterViewInit() {
debugger;
this.responseData = this.GetCurrentUserInformation();
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
}
When I check the this.responseData it is always returning this instead I want data:
I just want to make a sync call so I can get the data immediately.
I also tried to use the do() in service but its returning do() is not a function.
回答1:
this can be simplify by using 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();
}
}
回答2:
Subscribe to GetCurrentUserData()
the http call is async (every browser api call is async, because the javascript engine runs in a single thread (google for browser event loop for more, this is not an angular issue))
this.GetCurrentUserInformation().subscribe((data: ResponseData) => {
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
});
回答3:
Asynchronous functions cannot be called synchronously, because they are asynchronous.
subscribe
generally shouldn't performed in methods that are expected to be chained. Even if it should, an observable and not a subscription should be returned from a method (a subscription can be additionally saved to be unsubscribed on destruction).
GetCurrentUserInformation
method is redundant because it is just a wrapper for service call. The code can be refactored to:
ngAfterViewInit() {
this.loginService.GetCurrentUserData().subscribe(data => {
this.responseData = data;
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
});
}
回答4:
To make sure your async calls are executed before processing response you may use Observable.forkJoin() from ReactiveX.
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() function's onNext handler will execute when all HTTP requests complete successfully.
Required imports:
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
You may find more in this article.
回答5:
there is no direct way to make a synchronous call, however you can do the following procedure (this code is written in 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);
}
}
来源:https://stackoverflow.com/questions/47605737/how-to-make-a-synchronous-call-in-angular-5