Agular 中的 RxJS 之 Subject

379 阅读3分钟

「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战

前言

在上一篇文章当中,我们介绍了可观察对象的一些特性,但是我们会发现,之前的可观察对象局限性很大,每当观察者订阅的时候就会触发逻辑,这似乎会不满足于某些情况,比方说我不想要订阅的时候调用,我想要在之后某个实际再来一起调用可以吗,是可以的,这篇文章我们就来介绍一下 Subject 如何用来创建可观察对象。

Subject

Subject 是 RxJS 提供给我们的一个构造函数,用它也可以创建一个可观察对象,并且使用这个构造函数创建出来的可观察对象是一个空的可观察对象,在实例化的时候也不需要传入任何的参数,并且在被观察者订阅的时候,也不会立刻去调用内部的逻辑,只有在 next 方法被调用之后,才会去调用所以观察者的 next 方法。

这点调用的方式,是一种广播的调用方式,观察者们订阅可观察对象,当我需要的时候,可观察对象会去广播通知所有的观察者。

接下来我们来看一段代码:

import { Subject } from "rxjs";

const mySubject = new Subject();

const observer1 = {
  next: (value) => {
    console.log("observer1", value);
  },
};

const observer2 = {
  next: (value) => {
    console.log("observer2", value);
  },
};

mySubject.subscribe(observer1);
mySubject.subscribe(observer2);

setTimeout(() => {
  mySubject.next("我被调用了");
}, 3000);

// 输出
observer1 我被调用了
observer2 我被调用了

上面代码中,在观察者订阅可观察对象之后,并不会马上执行 next 方法,而是会等待 3 秒之后由可观察对象来广播发布 next 方法才会被调用。

BehaviorSubject

BehaviorSubject 也是一个构造函数,并且也是用于创造可观察对象的,它有着 Subject 所以的功能。

BehaviorSubject 相比于 Subject 它能够在实例化的时候传入一个默认值,并且观察者在订阅之后会立刻得到这个默认值,那么这里就是两个构造函数不同之处了,BehaviorSubject 创造的可观察对象在被订阅之后会立刻执行,而 Subject 创造的则不会。

下面我们来看一段代码:

import { BehaviorSubject } from "rxjs"

const myBehaviorSubject = new BehaviorSubject("默认值")

const observer = {
  next: (value) => {
    console.log("observer ", value);
  },
};

myBehaviorSubject.subscribe(observer);

setTimeout(() => {
    myBehaviorSubject.next("我被调用了");
}, 3000);

// 输出
observer 默认值
observer 我被调用了

可以看到这个可观察对象与上一个的不同之处,就是被订阅之后会立刻使用默认值执行一次。

ReplaySubject

ReplaySubject 也是和 Subject 功能类似,不同之处在于:在有新的订阅者订阅时,Subject 不会广播历史结果,而 ReplaySubject 会将历史结果也进行一个广播

我们来用一段实际代码演示一下:

import { ReplaySubject } from "rxjs";

const myReplaySubject = new ReplaySubject();

const observer1 = {
  next: (value) => {
    console.log("observer1 ", value);
  },
};

const observer2 = {
  next: (value) => {
    console.log("observer2 ", value);
  },
};

myReplaySubject.subscribe(observer1);

myReplaySubject.next("Hello World")

setTimeout(() => {
  myReplaySubject.subscribe(observer2);
}, 3000);

// 输出
observer1 Hello World
observer2 Hello World

在 next 方法调用了第一个订阅者的逻辑之后,过了三秒再去添加第二个订阅者,控制台还是会输出 第二个订阅者的订阅方法。

所以说,ReplaySubject 创建的可观察对象,会对历史广播结果做一个保存,再有新的观察者订阅的时候,会对它们进行广播。然而 Subject 创建的可观察对象就不会进行历史广播。

总结

本篇总结了三种不同的创建可观察对象的方法,分别是三个构造函数 Subject, BehaviorSubject 和 ReplaySubject,它们总体的作用都是为了创建可观察对象,并且创建出来的可观察对象会有着不同的特殊方法,这就需要在对应需要的时刻创建对应的可观察对象。

在接下去的文章当中,我们将会继续去介绍 RxJS 的相关方法已经简单使用。