Angular promises and observables are important concepts for any web developer performing asynchronous tasks to master. While the Promises cover a single value, asynchronous at that, the Observables handle multiple values over time and are more flexible.
This blog compares and contrasts the two and how they can be used in conjunction with Angular applications.
Angular Promise vs Observable: Key Differences Unlocked
1. Promise handles one value while Observables handles multiple values
One of the major changes which makes Observable & Angular Promise completely different is their ability to change the fulfilled value. Thus, you can just emit (reject or resolver) a single value for your Angular app.
For you to be able to grasp this concept, it is important that you possess a certain level of information regarding what is angular.
And if we talk about Observables, you can freely emit multiple results. The subscriber will receive results until the observer is done or unsubscribed.
Now let’s look at an example of working with values in terms of Angular Promise vs Observable.
// Promises
const x = new Promise((resolve) => {
setInterval(() => {
// ✅ when resolve is called, the promise will become
// fullfilled and it's value won't ever change
resolve(Math.random() * 10)
}, 3000);
});
// Observables
const observable$ = rxjs.Observable.create((observer) => {
// ✅ you can pass multiple values by using `next` method
observer.next(1);
observer.next(2);
observer.next(3);
observer.complete();
})
// ✅ base will be receiving values untils it's completed
observable$
.subscribe(
v => console.log(v),
err => console.log(err),
done => console.log("completed")
);
Observables are reactive tools that immediately respond to data feeds. In addition, there exists a bidirectional kind of Observable: Users, and they are a perfect example of those web sockets subjects. The RxJS library assists you in handling shipping with a thin wrapper on web sockets.
Observable Subscriptions vs Promises: Cancellability and Flexibility
When an Angular promise is initiated, it appears to be almost impossible to stop the event from occurring. Thus, the only thing that the callback passed to the Promise constructor does is to resolve or reject the Promise.
The subscriber-only reacts to the result once fired; therefore, it is entirely passive.
Observables are less passive with the subscribe creation process as compared to Angular Promise. This allows quick opt out of the observer at any time.
Therefore, if you are not very keen on receiving the response, you can choose such situations.
Indeed, there are several possibilities to cancel/complete subscribers.
Some common canceled subscribers are:
- unsubscribe: It enables you to cancel the subscription from the Observation on its own.
- take: It allows you to have number X of elements and unsubscribe easily from the process.
- takeUntil: It makes it easier for you to take values until the passed Observable emits any value.
Example of Cancelling Observable Subscriptions
Cancelling using unsubscribe:
const observable1$ = rxjs.interval(1000); // emits value every second
const subscription1$ = observable1$.subscribe(x => console.log(x));
subscription1$.unsubscribe(); // stops the subscription
Cancelling using take:
const observable2$ = rxjs.interval(1000); // emits value every second
observable2$
.pipe(rxjs.operators.take(5)) // takes only the first 5 emissions
.subscribe(x => console.log(x));
Cancelling using takeUntil:
const subject3$ = new rxjs.Subject();
const observable3$ = rxjs.interval(1000); // emits value every second
observable3$
.pipe(rxjs.operators.takeUntil(subject3$)) // stops when subject3 emits
.subscribe(x => {
console.log(x);
if (Math.random() > 0.5) { // randomly stop the stream
subject3$.next(1);
subject3$.complete();
console.log('complete');
}
});
So?
The cancellation feature of Observable subscriptions is more advantageous because developers can easily deal with resource management in large applications. The ability to use operators such as take, takeUntil, and unsubscribe makes Observables a very effective tool for managing asynchronous processes in Angular.
Best Angular Open-Source Chart Libraries to integrate interactive and visually appealing charts into their Angular applications.
Eager vs Lazy Execution:
In the comparison of Angular Promise & Observable, it is necessary to consider the process of execution. And that is done using the Eager and Lazy execution method.
Let’s put it simply. It is important to know that you can consume the Angular Promises eagerly. On the other hand, Observables are executed lazily and the observer can get data without having to make an actual request.
What is the difference between Lazy and Eager?
- Eager: It enables you to run the Promise callback particularly at the constructor level.
- Lazy: The Producer function will only execute after a subscription has been made to that Observable. Otherwise, it will stay idle.
Example of Eager Execution with a Promise:
const demoPromise = new Promise((resolve,reject) => {
console.log('1. first execution'); // executed immediately
resolve(true);
});
demoPromise.then(() => {
console.log('2. Promise resolution');
});
console.log('3. Pre exit method statement');
// Output:
// 1. first execution
// 3. Pre exit method statement
// 2. Promise resolution
Example of Lazy Execution with an Observable:
const observable$ = new rxjs.Observable(observer => {
console.log('1. Execution of observable body'); // executed only after subscription
observer.next(1);
observer.complete();
});
console.log('2. Pre Subscribe statement');
observable$.subscribe(() => {
console.log('3. Execution of subscribe callback');
});
// Output:
// 2. Pre Subscribe statement
// 1. Execution of observable body
// 3. Execution of subscribe callback
This difference makes Observables more versatile especially when data emissions may or may not be needed depending on user input or some conditions thus making efficient use of resources.
Interoperability
Yes, Angular Promises and Observables are different but the key question is whether we can use both of them simultaneously. The answer is yes; both can be used together and can be substituted by one another when necessary.
It is convenient to create an observable from a Promise & vice versa, an observable can be converted to a Promise. Because Promises work with only one value, it becomes important to decide which of the emitted values should be passed to the Promise.
In such situations, the RxJS library offers utility functions like firstValueFrom and lastValueFrom. Below is a simple example to demonstrate the interoperability between the two:
// ✅ Observable -> Promise
const source$ = rxjs.interval(2000).pipe(rxjs.operators.take(10));
// Using firstValueFrom to get the first emitted value
const result = await rxjs.firstValueFrom(source$);
// This will output the first value emitted (0 in this case),
// after 2 seconds, since take(10) limits to 10 emissions
// ✅ Promise -> Observable
const promise = Promise.resolve(10);
rxjs.from(promise)
// outputs 10
.subscribe(item => console.log(item)); // Outputs: 10
Conclusion
In summary, Promises and Observables serve different purposes, with Promises suited for single-value responses and Observables ideal for multiple, ongoing events. Understanding how to use them interchangeably can streamline your development process. For more insights on optimizing your Angular projects, reach out to ABC for expert guidance and solutions.
Comments