BehaviorSubject

一般的 Subject 可能会存在这样一个问题,某个 Observer 订阅的时间太晚了,导致他错过了最近的 Observable 发出的值:

const subject = new Rx.Subject();

const observerA = {
  next: x => console.log(`A next ${x}`),
  error: e => console.error(`A error ${e}`),
  complete: () => console.log('A done')
};

subject.subscribe(observerA);
console.log('observerA subscribed');

const observerB = {
  next: x => console.log(`B next ${x}`),
  error: e => console.error(`B error ${e}`),
  complete: () => console.log('B done')
};


subject.next(1);
subject.next(2);
subject.next(3);

setTimeout(() => {
  subject.subscribe(observerB);
  console.log('observerB subscribed');
}, 2000);

/* 程序输出:
  "observerA subscribed"
  "A next 1"
  "A next 2"
  "A next 3"
  "observerB subscribed"
 */

查看例子

在这个例子中,observerB 就因为订阅地太晚了,错过了 subject 最新发出的值 3

subject:   1--2--3
observerA: 1--2--3
observerB:           B

如果我们想各个观察者总能看到最近一次的值,那么就可以使用 BehaviorSubject

const subject = new Rx.BehaviorSubject(0);

const observerA = {
  next: x => console.log(`A next ${x}`),
  error: e => console.error(`A error ${e}`),
  complete: () => console.log('A done')
};

subject.subscribe(observerA);
console.log('observerA subscribed');

const observerB = {
  next: x => console.log(`B next ${x}`),
  error: e => console.error(`B error ${e}`),
  complete: () => console.log('B done')
};


subject.next(1);
subject.next(2);
subject.next(3);

setTimeout(() => {
  subject.subscribe(observerB);
  console.log('observerB subscribed');
}, 2000);

/* 程序输出:
  "A next 0"
  "observerA subscribed"
  "A next 1"
  "A next 2"
  "A next 3"
  "B next 3"
  "observerB subscribed"
 */

查看例子

确切的说,BehaviorSubject 并不只是留住了最后一次值,而是只有一个值,它反映了 “ 随时间变化的值 ” 。因此,在使用 BehaviorSubject 时,需要确定初始值。一个现实中的能反映 Subject 和 BehaviorSubject 区别的例子,就是 年龄生日。人只有一个年龄,并且始终拥有年龄,它随着时间变化,是一个单值的变化,所以是一个 BehaaviorSubject,而生日则每隔一年都会到来,是一个事件流,所以是一个 Subject。

results matching ""

    No results matching ""