您的位置:

RxJsSubject详解

一、RxJsSubject是什么

RxJsSubject是RxJs中的一种Subject类型,它既是一个Observable对象,又是一个Observer对象。作为Observable对象,它可以被subscribe用来订阅事件流;作为Observer对象,它可以被next、error、complete等方法使用来向对应的Observable流中传送数据,将自身作为观察者加入到事件流中。

RxJsSubject是RxJs中的一个重要类型,使用它可以实现可传递数据的多播,可以在多个地方共享同一份数据。它是RxJs中一种比较特殊的Subject类型,它具有很多独特的功能和使用场景。

二、RxJsSubject的优势

RxJsSubject有很多优势,比如:

1、多播功能:可以将同一份数据在多个地方共享;

2、可传递性:可以将Subject作为数据源来传递数据;

3、可控性:可以通过Subject的next、error、complete等方法来手动控制Observable的流向以及事件的发射顺序和时间;

4、便利性:可以在Observable对象订阅前/后、事件发射前/后、任意场景下使用next、error、complete等方法以及其他Observable的操作符来操作数据,非常方便实用。

三、RxJsSubject的基本使用

下面是一个简单的RxJsSubject的使用示例:


const subject = new Rx.Subject();

subject.subscribe({
  next: (v) => console.log(`observerA: ${v}`)
});

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

subject.subscribe({
  next: (v) => console.log(`observerB: ${v}`)
});

subject.next(3);
subject.next(4);

上面的代码中,定义了一个Rx.Subject类型的Subject对象,并通过subscribe方法向其订阅了两个观察者,通过next方法向Observable对象中传送数据。执行结果如下:


observerA: 1
observerA: 2
observerA: 3
observerA: 4
observerB: 3
observerB: 4

从结果可以看出,我们通过Subject共享了两个观察者的数据,它们都收到了相同的4条数据。

四、RxJsSubject的高级用法

RxJsSubject有很多高级用法,下面是其中一些:

1、BehaviorSubject

BehaviorSubject是RxJsSubject中的一种,它与普通的Subject的唯一区别是,BehaviorSubject会保存最新的数据,并在新增订阅时立即将这个最新数据发射给新的订阅者。我们可以通过BehaviorSubject的构造函数为其设置一个初始值,这个初始值也会在新增订阅时发射给新的订阅者。

下面是BehaviorSubject的一个示例:


const subject = new Rx.BehaviorSubject(0);

subject.subscribe({
  next: (v) => console.log(`observerA: ${v}`)
});

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

subject.subscribe({
  next: (v) => console.log(`observerB: ${v}`)
});

subject.next(3);

上面的代码中,我们以0为初始数据创建了一个BehaviorSubject类型的Subject对象,并分别向其新增了两个观察者。执行结果如下:


observerA: 0
observerA: 1
observerA: 2
observerB: 2
observerA: 3
observerB: 3

从结果可以看出,在新增观察者2后,它立即收到了最新数据2。同时,观察者1和新增观察者2都收到了5次数据。这也是因为BehaviorSubject会保存最新的数据并在新增订阅时立即发射给新的订阅者的原因。

2、ReplaySubject

ReplaySubject是RxJsSubject中的一种,它与普通的Subject的唯一区别是,ReplaySubject会缓存所有的数据并在新增订阅时立即将缓存的数据发射给新的订阅者。我们可以通过ReplaySubject的构造函数来为其设置缓存的数据大小。

下面是ReplaySubject的一个示例:


const subject = new Rx.ReplaySubject(2);

subject.subscribe({
  next: (v) => console.log(`observerA: ${v}`)
});

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

subject.subscribe({
  next: (v) => console.log(`observerB: ${v}`)
});

subject.next(5);

上面的代码中,我们以2为ReplaySubject的缓存大小创建了一个Subject对象,并分别向其新增了两个观察者。执行结果如下:


observerA: 1
observerA: 2
observerA: 3
observerA: 4
observerB: 3
observerB: 4
observerB: 5

从结果可以看出,新增观察者2收到了3条缓存数据,也就是前面的2和3。同时,观察者1共收到了5条数据。

总结

RxJsSubject是一个非常实用的RxJs类型,它可以帮助我们实现可传递数据的多播。我们可以使用不同的Subject类型来实现不同的功能,比如BehaviorSubject和ReplaySubject等。在RxJs中,使用Subject类型非常常见,特别是在多组件之间共享数据时,Subject几乎是一种必须的类型。