我正在研究Angular RxJs模式,我不明白行为主体和可观察对象之间的区别。

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

什么时候使用可观察对象和行为主体?使用一个行为主体比使用一个可观察对象有好处吗?反之亦然?


当前回答

我在例子中没有看到的一件事是,当你通过asObservable将BehaviorSubject转换为Observable时,它继承了订阅时返回最后一个值的行为。

这是很棘手的一点,因为库通常会将字段作为可观察对象公开(例如,在Angular2中ActivatedRoute中的参数),但可能会在幕后使用Subject或BehaviorSubject。他们使用什么会影响订阅行为。

请看这里http://jsbin.com/ziquxapubo/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);

其他回答

行为主体vs可观察对象:RxJS有观察者和可观察对象,RxJS提供了多个用于数据流的类,其中一个是行为主体。

可观察对象:可观察对象是多个值随时间变化的惰性集合。

BehaviorSubject:一个需要初始值并将其当前值发送给新订阅者的Subject。

 // RxJS v6+
import { BehaviorSubject } from 'rxjs';

const subject = new BehaviorSubject(123);

//two new subscribers will get initial value => output: 123, 123
subject.subscribe(console.log);
subject.subscribe(console.log);

//two subscribers will get new value => output: 456, 456
subject.next(456);

//new subscriber will get latest value (456) => output: 456
subject.subscribe(console.log);

//all three subscribers will get new value => output: 789, 789, 789
subject.next(789);

// output: 123, 123, 456, 456, 456, 789, 789, 789

你也可以像这样将一个主题更改为一个可观察对象:

 page = new BehaviorSubject<String|null>(null);
 actualPage:Observable<string> = new Observable()

this.page.next("hardware")
this.actualPage = this.page as Observable<any>;

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

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

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

这会导致主要的错误和低效率

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

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>

输出:

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

观察如何使用Observable。create为每个观察者创建了不同的输出,但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                          ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

可观测的 是通用的,

可观察对象是多个值随时间变化的惰性集合。

只是一个函数,没有状态

为每个观察者运行代码

BehaviorSubject: 一个需要初始值并将其当前值发送给新订阅者的主题。

在技术上是Observable的子类型,因为BehaviorSubject是一个具有特定品质的可观察对象。

有状态。在内存中存储数据

相同的代码只对所有观察者运行一次

行为主体的独特特征如下:

它需要一个初始值,因为它必须总是在订阅时返回一个值,即使它没有接收到next()

在订阅时,它返回主题的最后一个值。常规可观察对象只有在接收到onnext时才会触发

在任何时候,您都可以使用getValue()方法在不可观察的代码中检索主题的最后一个值。

Observable对象表示一个基于推的集合。

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

Subject类继承了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