行为主体与可观察?

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

根据我的理解,a是一个可以随时间变化的值(可以订阅,订阅者可以接收更新的结果)。这似乎与 .BehaviorSubjectObservable

你什么时候会使用 vs a ?使用 a over an 或反之亦然有什么好处?ObservableBehaviorSubjectBehaviorSubjectObservable


答案 1

BehaviorSubject是一种主题,主题是一种特殊类型的可观察对象,因此您可以像订阅任何其他可观察消息一样订阅消息。BehaviorSubject的独特之处在于:

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

与可观察对象相比,受试者的独特之处在于:

  • 除了是可观察对象之外,它还是观察者,因此除了订阅主题之外,您还可以向主题发送值。

此外,您可以使用 上的方法从行为主体获得可观察性。asObservable()BehaviorSubject

Observable 是一个 Generic,从技术上讲,它是 Observable 的子类型,因为 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 won't get 
                                          // anything at this point
});

subject.next("c"); // Subscription got c
subject.next("d"); // Subscription got d

可以从两者创建可观察量,并使用 。SubjectBehaviorSubjectsubject.asObservable()

唯一的区别是您无法将值发送到可观察的 using 方法。next()

在 Angular 服务中,我将用于数据服务,因为 Angular 服务通常在组件和行为主体确保使用该服务的组件接收上次更新的数据之前进行初始化,即使该组件订阅此数据后没有新的更新。BehaviorSubject


答案 2

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

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

将为每个观察者运行代码。如果它是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));
<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"

观察 using 如何为每个观察者创建不同的输出,但为所有观察者提供相同的输出。这很重要。Observable.createBehaviorSubject


总结了其他差异。

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃         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                          ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛