BehaviorSubject vs Observable?

I'm looking into Angular RxJs patterns and I don't understand the difference between a BehaviorSubject and an Observable .

From my understanding, a BehaviorSubject is a value that can change over time (can be subscribed to and subscribers can receive updated results). This seems to be the exact same purpose of an Observable .

When would you use an Observable vs a BehaviorSubject ? Are there benefits to using a BehaviorSubject over an Observable or vice versa?


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() . 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 a 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>

    The Observable object represents a push based collection.

    The Observer and Observable interfaces provide a generalized mechanism for push-based notification, also known as the observer design pattern. The Observable object represents the object that sends notifications (the provider); the Observer object represents the class that receives them (the observer).

    The Subject class inherits both Observable and Observer, in the sense that it is both an observer and an observable. You can use a subject to subscribe all the observers, and then subscribe the subject to a backend data source

    var subject = new Rx.Subject();
    
    var subscription = subject.subscribe(
        function (x) { console.log('onNext: ' + x); },
        function (e) { console.log('onError: ' + e.message); },
        function () { console.log('onCompleted'); });
    
    subject.onNext(1);
    // => onNext: 1
    
    subject.onNext(2);
    // => onNext: 2
    
    subject.onCompleted();
    // => onCompleted
    
    subscription.dispose();
    

    More on https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md

    链接地址: http://www.djcxy.com/p/55474.html

    上一篇: 承诺和观察

    下一篇: BehaviorSubject vs Observable?