BehaviorSubject与Observable?

我正在研究Angular RxJs模式,我不明白BehaviorSubject和Observable之间的区别。

根据我的理解,BehaviorSubject是一个可以随时间变化的值(可以订阅,订阅者可以收到更新后的结果)。 这似乎是一个Observable完全相同的目的。

什么时候你会使用一个Observable vs一个BehaviorSubject? 通过Observable使用BehaviorSubject是否有好处,反之亦然?

BehaviorSubject是一种主体,主体是一种特殊的可观察types,所以您可以像其他可观察的一样订阅消息。 BehaviorSubject的独特function是:

  • 它需要一个初始值,因为它必须总是返回一个值,即使它没有收到next()
  • 订阅后,它返回主题的最后一个值。 一个常规的observable只有在接收到一个onnext时才会触发
  • 在任何时候,您都可以使用getValue()方法检索不可观察代码中主题的最后一个值。

与可观察对象相比,主题的独特特征是:

  • 这是一个观察者,除了作为一个观察者,所以你也可以发送价值的主题,除了订阅它。

此外,您还可以使用BehaviorSubject上的asobservable()方法从行为主题中获得可观察值。

Observable是Generic,而BehaviorSubject在技术上是Observable的子types,因为BehaviorSubject是具有特定属性的observable。

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 

示例2与常规主题:

 // 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 

可以使用subject.asobservable()从Subject和BehaviorSubject创build一个observable。 唯一不同的是,你不能使用next()方法将值发送给observable。

在Angular服务中,我将使用BehaviorSubject作为angular度服务的angular色服务,在组件和行为主体确保使用服务的组件接收最后一次更新的数据之前,经常进行初始化,即使组件订阅了此数据后没有新的更新。

可观察:每个观察者的结果不同

一个非常非常重要的区别。 由于Observable只是一个函数,它没有任何状态,所以对于每个新的Observer,它都会一次又一次地执行可观察的创build代码。 这导致:

代码是为每个观察者运行的。 如果它是一个HTTP调用,它会被每个观察者调用

这会导致重大的错误和低效率

BehaviorSubject(或Subject)存储观察者细节,只运行一次代码并将结果提供给所有观察者。

例如:

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)); 

输出:

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

观察如何使用Observable.create为每个观察者创build不同的输出,但BehaviorSubject为所有观察者提供相同的输出。 这个很重要。


其他差异总结。

 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ 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对象表示一个基于推送的集合。

Observer和Observable接口为基于推送的通知提供了一个通用机制,也称为观察者devise模式。 Observable对象表示发送通知的对象(提供者); Observer对象表示接收它们的类(观察者)。

Subject类inheritance了Observable和Observer,它既是观察者又是观察者。 您可以使用主题订阅所有观察者,然后将主题订阅到后端数据源

 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(); 

更多关于https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md

在示例中没有看到的一件事是,当通过asObservable将BehaviorSubject投射到Observable时,它会inheritance返回订阅上一个值的行为。

这是棘手的一点,因为经常图书馆会暴露字段作为可观察的(即参数Angular2中的ActivatedRoute),但可能使用主题或BehaviorSubject幕后。 他们使用什么会影响订阅的行为。

看到这里http://jsbin.com/ziquxapub//edit?html,js,console

 let A = new Rx.Subject(); let B = new Rx.BehaviorSubject(0); A.next(1); B.next(1); A.asObservable().subscribe(n => console.log('A', n)); B.asObservable().subscribe(n => console.log('B', n)); A.next(2); B.next(2);