什么是 RxJS Subject?
RxJS Subject 是 RxJS 库中最常用的一个类。 它既是一个 Observable,又是一个 Observer。 这意味着可以使用 Subject 来订阅 Observables,并像 Observer 一样发送新值(next),错误(error)和完成信号(complete)。
Subject 的基础用法
创建一个 Subject 可以使用 Subject 构造函数:
import { Subject } from 'rxjs'; const subject = new Subject<number>();
这里创建了一个 Subject 的实例,泛型参数指定了 Subject 所代表的值的类型。这里以 number 类型作为示例。
使用 next 方法向 Subject 发送值:
subject.next(1); subject.next(2);
此时 Subject 内部维护着一个值流(value stream),下游可以订阅(subscribe)这个 Subject,获取值流中的值:
const subscription = subject.subscribe({ next: value => console.log(value), }); // 输出: 1, 2
注意:如果先订阅后发送,订阅者无法接收到前面的值。
// 输出:空 const subscription = subject.subscribe({ next: value => console.log(value), }); subject.next(1); subject.next(2);
Subject 作为一个 observable,同样可以用于组合操作符(operators):
const doubled = subject.pipe(map(value => value * 2)); doubled.subscribe(value => console.log(value)); // 输出: 2, 4 subject.next(2); subject.next(4);
Subject 的高级用法
BehaviorSubject
BehaviorSubject 是一种特殊的 Subject。它会对新的观察者发送一个最新值,以便使观察者能够在订阅后立即看到一些值。
-- -------------------- ---- ------- ------ - --------------- - ---- ------- ----- --------------- - --- --------------------------- ------------------------ ------------------------------- -- -------------------- -- ---- ------------------------ -- ----
注意:如果没有传递初始值 0,第一个订阅者将收到一个 undefined 值。
ReplaySubject
ReplaySubject 会缓存一定数量的值并将其发送给所有订阅者。 这可以用于回溯可能需要多次订阅的事件(类似视频播放器中的播放器进度条)。
-- -------------------- ---- ------- ------ - ------------- - ---- ------- ----- ------------- - --- ------------------------ ---------------------- ---------------------- ---------------------- ----------------------------- -- -------------------- -- ----- -- - ---------------------- -- ----
AsyncSubject
AsyncSubject 仅在源 Observable 完成后才将其最后一个值发送给订阅者。 它将这个值缓存,以便在新的订阅者订阅时能立即获取到该值。
-- -------------------- ---- ------- ------ - ------------ - ---- ------- ----- ------------ - --- ----------------------- --------------------- --------------------- ---------------------------- -- -------------------- -- ----- --------------------- ------------------------ -- ----
从 Subject 到 BehaviorSubject 的转换
一种常见的情况是:我们希望在应用程序中共享某些值并确保下游始终具有最新值。 在这种情况下,BehaviorSubject 可能是最好的选择。由于 BehaviorSubject 要求在创建时提供一个默认值,因此需要在应用程序中赋值。
import { BehaviorSubject } from 'rxjs'; export const sharedValue$ = new BehaviorSubject<number>(0); function updateSharedValue(newValue: number) { sharedValue$.next(newValue); }
总结
RxJS 中的 Subject 可以在很多场景下发挥重要的作用,既可以作为异步任务的拦截器(如节流),还可以作为多个订阅者的共享值。了解这些不同类型的 Subject 可以帮助我们更好地应用到实践中。
完整代码:
-- -------------------- ---- ------- ------ - ---------------- -------------- ------------ - ---- ------- ------ - --- - ---- ----------------- ----- ------- - --- ------------------ -- ---- ---------------- ---------------- ----- ------------ - ------------------- ----- ----- -- ------------------- --- -- --- -- - ----- ------- - ---------------------- -- ----- - ---- ----------------------- -- -------------------- -- --- -- - -- --------------- ----- --------------- - --- --------------------------- ------------------------ ------------------------------- -- -------------------- -- ---- ------------------------ -- ---- -- ------------- ----- ------------- - --- ------------------------ ---------------------- ---------------------- ---------------------- ----------------------------- -- -------------------- -- ----- -- - ---------------------- -- ---- -- ------------ ----- ------------ - --- ----------------------- --------------------- --------------------- ---------------------------- -- -------------------- -- ----- --------------------- ------------------------ -- ---- -- - ------- - --------------- --- ------ ----- ------------ - --- --------------------------- -------- --------------------------- ------- - ---------------------------- -
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6485a1f548841e9894463c56