Consider the following two methods in a Service
for querying a webservice:
getAssessmentById(id: number): Observable<MotorAssessorReport> {
const url = environment.endPoints.assessment.base +
environment.endPoints.assessment.assessmentById + id;
return this.httpClient.get<MotorAssessorReport>(url)
}
async getAssessmentByIdAsync(id: number): Promise<MotorAssessorReport> {
const url = environment.endPoints.assessment.base +
environment.endPoints.assessment.assessmentById + id;
const data = await this.httpClient.get<MotorAssessorReport>(url).toPromise();
return data;
}
The first method, getAssessmentById
returns an observable
. The second method, getAssessmentByIdAsync
, returns a promise
.
subscribeToAssessment() {
this.assessmentService.getAssessmentById(this.assessmentId).subscribe(result =>
{
this.assessment = result;
});
}
async fetchAssessment() {
this.assessment = await this.assessmentService.getAssessmentByIdAsync(this.assessmentId);
}
I have always been using the first approach, returning an Observable<T>
, and subscribing in my calling code.
I recently truely began to understand that this approach should only really be used if you expect multiple results to be returned. In other words, when using a Promise<T>
, the maximum amount the callback is called, is only once.
Since I have been expecting my server to only always be returning once, is my approach wrong, and should I rather be using the Promise<T>
approach, combined with async/await
?
I think you also have to remember the difference between hot and cold observables (see this question. Since httpClient
is a cold observable, it will make the request for each call and you don't need to worry about unsubscribing afterward. The main difference between your two methods is when the http request is made. In the observable method, the request won't be made until .subscribe
is called. In the promise version, the request will be made immediately. I agree with @kasperlauge that, in most cases, observables should be preferred.
I would say that in most cases where you can use promises, observables can do it better! One key advantage of observables is that they can be canceled (by unsubscibing to the subscription). That is a feature which is also useful when only returning a single value.
Further more all the operator functions of observables handling multiple parallel async requests is far easier to use than to manually brew some promise handling together.
If you want to avoid unsubscribing to trivial observables/subscriptions, you can use the take(1) operator function which makes sure you do not get unexpected function call (if you forgot to unsubscribe).
This would be done as:
this.assessmentService.getAssessmentById(this.assessmentId)
.pipe(take(1))
.subscribe(result =>
{
this.assessment = result;
});
If only simple async tasks is needed, rxjs can be unnecessary and promises can be used instead. The advantages of using promises from my perspective is the cleaner syntax using async/await and the native support (not needing to rely on a third-party library).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With