问题
I have a service that has a method foo. Inside the method I subscribe to an observable (http-client).
foo () : boolean
{
let ret : false;
this.http.get ("/blabla").subscribe (
(resp) =>
{
ret = true;
}
return ret;
);
I like to return a boolean value from foo that depends on the get. That is not working because http.get is asynchrouns - return is called before http.get finished.
How can I make this synchronous?
EDIT
Returning the observable instead boolean is not an option here. That is because I handle the response of get in foo (not shown here) but I also need to act out of foo depending of its return.
EDIT2
I extended my sample with pipe and tap. Now I return the http.get-observable for outside the service and I process the http.get-result with tap.
foo () : Observable <any>
{
return this.http.get ("/blabla").pipe (tap (x => handlehere ()));
}
As far I see there is only one uglyness with it. I have the complexity of parsing the get-result inside AND outside of foo. I would prefer a simple boolean outside of foo.
回答1:
This method can only run asynchronously so you don't have a lot of option. Returning the obsersable and subscribe or return a promise. Perhaps returning a Promise will suite more your need in term of comprehention.
In your service : the foo method :
async foo() {
const result = await this.http.get("/blabla").toPromise();
// do what you want with result
return result;
}
How to call it :
this.myService.foo().then( (result) => {
// Do what you want with the result
});
回答2:
If you really must return a boolean here's a way:
private ret = false;
constructor()
this.http.get("/blabla").subscribe ((resp) => {
this.ret = true;
}
}
foo(): boolean {
return this.ret;
}
The thing with the above approach is that the service makes the HTTP async call immediately and never makes it again, which is fine if the response data never changes. This is an example of caching. However, if the response data changes frequently then the above is no good.
A more standard approach is returning an Observable like so:
foo() {
return this.http.get("/blabla")
}
and in the call to this method:
this.myService.foo().subscribe((resp) => {
this.ret = true;
}
Here the async HTTP request is made every time you call this.myService.foo()
来源:https://stackoverflow.com/questions/52485266/angular-rxjs-synchronous-observable