BehaviorSubject Vs Observable?


Answer :

BehaviorSubject is a type of subject, a subject is a special type of observable so you can subscribe to messages like any other observable. The unique features of BehaviorSubject are:

  • It needs an initial value as it must always return a value on subscription even if it hasn't received a next()
  • Upon subscription, it returns the last value of the subject. A regular observable only triggers when it receives an onnext
  • at any point, you can retrieve the last value of the subject in a non-observable code using the getValue() method.

Unique features of a subject compared to an observable are:

  • It is an observer in addition to being an observable so you can also send values to a subject in addition to subscribing to it.

In addition, you can get an observable from behavior subject using the asObservable() method on BehaviorSubject.

Observable is a Generic, and BehaviorSubject is technically a sub-type of Observable because BehaviorSubject is an observable with specific qualities.

Example with BehaviorSubject:

// Behavior Subject  // a is an initial value. if there is a subscription  // after this, it would get "a" value immediately let bSubject = new BehaviorSubject("a");   bSubject.next("b");  bSubject.subscribe(value => {   console.log("Subscription got", value); // Subscription got b,                                            // ^ This would not happen                                            // for a generic observable                                            // or generic subject by default });  bSubject.next("c"); // Subscription got c bSubject.next("d"); // Subscription got d 

Example 2 with regular subject:

// Regular Subject  let subject = new Subject();   subject.next("b");  subject.subscribe(value => {   console.log("Subscription got", value); // Subscription wont get                                            // anything at this point });  subject.next("c"); // Subscription got c subject.next("d"); // Subscription got d 

An observable can be created from both Subject and BehaviorSubject using subject.asObservable().

The only difference being you can't send values to an observable using next() method.

In Angular services, I would use BehaviorSubject for a data service as an angular service often initializes before component and behavior subject ensures that the component consuming the service receives the last updated data even if there are no new updates since the component's subscription to this data.


Observable: Different result for each Observer

One very very important difference. Since Observable is just a function, it does not have any state, so for every new Observer, it executes the observable create code again and again. This results in:

The code is run for each observer . If its a HTTP call, it gets called for each observer

This causes major bugs and inefficiencies

BehaviorSubject (or Subject ) stores observer details, runs the code only once and gives the result to all observers .

Ex:

JSBin: http://jsbin.com/qowulet/edit?js,console

// --- Observable --- let randomNumGenerator1 = Rx.Observable.create(observer => {    observer.next(Math.random()); });  let observer1 = randomNumGenerator1       .subscribe(num => console.log('observer 1: '+ num));  let observer2 = randomNumGenerator1       .subscribe(num => console.log('observer 2: '+ num));   // ------ BehaviorSubject/ Subject  let randomNumGenerator2 = new Rx.BehaviorSubject(0); randomNumGenerator2.next(Math.random());  let observer1Subject = randomNumGenerator2       .subscribe(num=> console.log('observer subject 1: '+ num));        let observer2Subject = randomNumGenerator2       .subscribe(num=> console.log('observer subject 2: '+ num));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.3/Rx.min.js"></script>

Output :

"observer 1: 0.7184075243594013" "observer 2: 0.41271850211336103" "observer subject 1: 0.8034263165479893" "observer subject 2: 0.8034263165479893" 

Observe how using Observable.create created different output for each observer, but BehaviorSubject gave the same output for all observers. This is important.


Other differences summarized.

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃         Observable                  ┃     BehaviorSubject/Subject         ┃       ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫  ┃ Is just a function, no state        ┃ Has state. Stores data in memory    ┃ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ Code run for each observer          ┃ Same code run                       ┃ ┃                                     ┃ only once for all observers         ┃ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ Creates only Observable             ┃Can create and also listen Observable┃ ┃ ( data producer alone )             ┃ ( data producer and consumer )      ┃ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ ┃ Usage: Simple Observable with only  ┃ Usage:                              ┃ ┃ one Obeserver.                      ┃ * Store data and modify frequently  ┃ ┃                                     ┃ * Multiple observers listen to data ┃ ┃                                     ┃ * Proxy between Observable  and     ┃ ┃                                     ┃   Observer                          ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ 

Observable and subject both are observable's means an observer can track them. but both of them have some unique characteristics. Further there are total 3 type of subjects each of them again have unique characteristics. lets try to to understand each of them.

you can find the practical example here on stackblitz. (You need to check the console to see the actual output)

enter image description here

Observables

They are cold: Code gets executed when they have at least a single observer.

Creates copy of data: Observable creates copy of data for each observer.

Uni-directional: Observer can not assign value to observable(origin/master).

Subject

They are hot: code gets executed and value gets broadcast even if there is no observer.

Shares data: Same data get shared between all observers.

bi-directional: Observer can assign value to observable(origin/master).

If are using using subject then you miss all the values that are broadcast before creation of observer. So here comes Replay Subject

ReplaySubject

They are hot: code gets executed and value get broadcast even if there is no observer.

Shares data: Same data get shared between all observers.

bi-directional: Observer can assign value to observable(origin/master). plus

Replay the message stream: No matter when you subscribe the replay subject you will receive all the broadcasted messages.

In subject and replay subject you can not set the initial value to observable. So here comes Behavioral Subject

BehaviorSubject

They are hot: code gets executed and value get broadcast even if there is no observer.

Shares data: Same data get shared between all observers.

bi-directional: Observer can assign value to observable(origin/master). plus

Replay the message stream: No matter when you subscribe the replay subject you will receive all the broadcasted messages.

You can set initial value: You can initialize the observable with default value.


Comments

Popular posts from this blog

Are Regular VACUUM ANALYZE Still Recommended Under 9.1?

Can Feynman Diagrams Be Used To Represent Any Perturbation Theory?