RxJS笔记(四)Subject主体
创始人
2025-05-31 15:10:25
0

文章目录

    • 多播 Observables (Multicasted Observables)
        • 引用计数 refCount()
    • 1. 行为主体 BehaviorSubject
    • 2. 重播主体 ReplaySubject
    • 3. 异步主体 AsyncSubject
    • 4. void 主体 Void subject

普通的 Observable 是单播的(每个订阅的 Observer 都拥有 Observable 的独立执行)

Subject是一种特殊类型的 Observable,允许将值多播到多个 Observer

Subjects 就像 EventEmitters:它们维护着许多监听器的注册表。

  1. 每个 Subject 都是 Observable。
    给定一个 Subject,你可以 subscribe 它,提供一个 Observer,它将开始正常接收值。
    从 Observer 的角度来看,它无法判断 Observable 的执行是来自普通的单播 Observable 还是来自 Subject。
  2. 每个 Subject 也都是 Observer。
    是一个具有方法 next(v)、error(e) 和 complete() 的对象。
    要为 Subject 提供一个新值,只需调用 next(theValue),它将被多播到注册进来监听 Subject 的 Observer。
    (由于 Subject 是 Observer,这也意味着你可以提供 Subject 作为任意 Observable subscribe 的参数
import { Subject, from } from 'rxjs';
const subject = new Subject();subject.subscribe({ next: (v) => console.log(`observerA: ${v}`),});
subject.subscribe({ next: (v) => console.log(`observerB: ${v}`),});const observable = from([1, 2, 3]);observable.subscribe(subject); // You can subscribe providing a Subject// Logs:
// observerA: 1
// observerB: 1
// observerA: 2
// observerB: 2
// observerA: 3
// observerB: 3
  • Subject 类型还有一些特化: BehaviorSubject、ReplaySubject 和 AsyncSubject。

多播 Observables (Multicasted Observables)

多播的 Observable 在底层使用 Subject 来让多个 Observer 看到相同的 Observable 执行过程。

  • e.g. multicast
import { from, Subject, multicast } from 'rxjs';const source = from([1, 2, 3]);
const subject = new Subject();
const multicasted = source.pipe(multicast(subject));// These are, under the hood, `subject.subscribe({...})`:
multicasted.subscribe({next: (v) => console.log(`observerA: ${v}`),
});
multicasted.subscribe({next: (v) => console.log(`observerB: ${v}`),
});// This is, under the hood, `source.subscribe(subject)`:
multicasted.connect();

multicast 返回一个 ConnectableObservable,它只是一个带有 connect() 方法的 Observable。
connect() 在后台执行 source.subscribe(subject),所以 connect() 返回一个订阅,你可以退订以取消共享的 Observable 执行过程。

引用计数 refCount()

手动调用 connect() 并处理订阅通常很麻烦。通常,我们希望在第一个 Observer 抵达时自动连接,并在最后一个 Observer 退订时自动取消共享执行。

e.g. 执行

  1. 第一个 Observer 订阅了多播的 Observable
  2. 多播的 Observable 已连接
  3. next 值 0 被传递给第一个 Observer
  4. 第二个 Observer 订阅了多播的 Observable
  5. next 的值 1 被传递给第一个 Observer
  6. next 的值 1 被传递给第二个 Observer
  7. 第一个 Observer 退订多播的 Observable
  8. next 值 2 被传递给第二个 Observer
  9. 第二个 Observer 退订多播的 Observable
  10. 与多播的 Observable 的连接被退订

refCount 能使多播的 Observable 在第一个订阅者抵达时自动开始执行,并在最后一个订阅者离开时停止执行。

const refCounted = source.pipe(multicast(subject), refCount());

refCount() 方法只存在于 ConnectableObservable 上,它返回一个 Observable,而不是另一个 ConnectableObservable。

1. 行为主体 BehaviorSubject

Subjects 的变体之一是 BehaviorSubject,它具有“当前值”的概念。
它存储发送给其消费者的最新值,并且每当有新的 Observer 订阅时,它将立即从 BehaviorSubject 接收到“当前值”

import { BehaviorSubject } from 'rxjs';
const subject = new BehaviorSubject(0); // 0 is the initial valuesubject.subscribe({next: (v) => console.log(`observerA: ${v}`),
});
subject.next(1);
subject.next(2);
subject.subscribe({next: (v) => console.log(`observerB: ${v}`),
});
subject.next(3);// Logs
// observerA: 0
// observerA: 1
// observerA: 2
// observerB: 2  //第二个 Observer 接收到值 2,即使它是在发送值 2 之后订阅的。
// observerA: 3
// observerB: 3

2. 重播主体 ReplaySubject

ReplaySubject 与 BehaviorSubject 类似,它可以将旧值发送给新订阅者,但它也可以记录 Observable 执行结果的一部分。

ReplaySubject 会记录来自 Observable 执行的多个值,并将它们重播给新订阅者。

可以指定要重播的值的数量

import { ReplaySubject } from 'rxjs';
const subject = new ReplaySubject(3); // buffer 3 values for new subscriberssubject.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);// Logs:
// observerA: 1
// observerA: 2
// observerA: 3
// observerA: 4
// observerB: 2
// observerB: 3
// observerB: 4
// observerA: 5
// observerB: 5

除了缓冲区大小之外,你还可以指定一个以毫秒为单位的窗口时间,以确定记录的值可以存在多长时间。

//使用 100 个元素的大型缓冲区,但窗口时间参数仅为 500 毫秒
const subject = new ReplaySubject(100, 500 /* windowTime */);

3. 异步主体 AsyncSubject

仅将 Observable 执行的最后一个值发送给其 Observer,并且仅在执行完成时发送

AsyncSubject 类似于 last() 操作符,因为它会等待 complete 通知以传递单个值。

import { AsyncSubject } from 'rxjs';
const subject = new AsyncSubject();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);
subject.complete();// Logs:
// observerA: 5
// observerB: 5

4. void 主体 Void subject

有时,发出值这件事本身比所发出的值更重要。
通过声明一个 void 主体,你可以表明该值是无所谓的。只有事件本身才重要。

import { Subject } from 'rxjs';// const subject = new Subject();
const subject = new Subject(); // Shorthand for Subjectsubject.subscribe({next: () => console.log('One second has passed'),
});setTimeout(() => subject.next(), 1000);

在版本 7 之前,Subject 值的默认类型是 any。
Subject 禁用发出值的类型检查,而 Subject 可以防止意外访问所发出的值。

相关内容

热门资讯

寻找宾馆服务成功人士的故事 寻找宾馆服务成功人士的故事快吧迈克是纽约一家小报的普通记者。一个周末,他在一家不大的酒店里看见几位身...
安徽男子在家按监控,发现妻子带... 安徽男子在家按监控,发现妻子带陌生男子回家过夜,妻子是如何解释的?妻子回应说只是同事,没有发生什么,...
关于宇宙的科幻小说 关于宇宙的科幻小说《沙丘》三部曲(经典!),《迟暮之战》,《安德的游戏》,《不锈钢老鼠的宇宙冒险》(...
兵团800多万亩农田穿上“环保... 本报乌鲁木齐讯(全媒体记者 孙永杰 通讯员 淮振杰 何琦艳) “使用加厚高强度地膜后,防风...
用什么成语形容月光 用什么成语形容月光皎洁,朦胧,隐涩、月光如水山高月小月色如银月明风清月朗星稀新月如钩晓月当帘月影婆娑...
我家的紫藤种了三年,前几年多好... 我家的紫藤种了三年,前几年多好的,今年到现在还没发芽长叶,是什么原因?到了5月万物复苏之际,紫藤树都...
适合女生看的书 适合女生看的书白羽著,挺好的,比如她说,对待男人的私房钱,聪明女人应该是心中有数,而不是随时准备戳穿...
历史人物能够进行比较吗?比如我... 历史人物能够进行比较吗?比如我把李白和诸葛亮比历史人物是可以进行比较的,但要有相同点。像诸葛亮和李白...
介绍几部好看的推理小说、最好是... 介绍几部好看的推理小说、最好是一章节一个故事的、谢谢7truth亡灵书每晚一个离奇故事吉祥纹莲花楼这...
急急急!!!求寻几张黄冈老照片... 急急急!!!求寻几张黄冈老照片背后的故事唉,太多了撒,那时俺们又都没有生出来,我只知道点把,罗田县响...
忘了我的歌,忘了我!没有自由的... 忘了我的歌,忘了我!没有自由的自由没有我的歌名是什么?任贤齐的飞鸟
卡通美甲觉得可爱,怎么画的呀 卡通美甲觉得可爱,怎么画的呀1.准备好所需的甲油和工具,修剪指甲并打磨好甲面,刷上底油,照灯60秒。...
培训机构软笔书法文案,软笔书法...   文/唐笑笑      后台回复“听课”,听免费课程。      后台回复“写作”,加入写作群。 ...
求一西部牛仔动画片,里面三头牛... 求一西部牛仔动画片,里面三头牛的故事这三头牛都是警察,伸张正义是叫哦,主角叫穆警官集数: 26国家/...
创业行为有哪些 创业行为有哪些...   很多朋友想创业,但是不知道从哪里入手,做什么?的确,创业遇到的第一个问题基本就是卖什么。那么,什...
最高50万元孵化资金 邀全球创... 转自:成都日报锦观四川启动短剧创作征集最高50万元孵化资金 邀全球创作者“剧绘四川” 近日,为...
2025上海国际碳中和博览会闭... 转自:财联社【2025上海国际碳中和博览会闭幕 三天共接待各地参观团101个】财联社6月7日电,20...
有梦就去追 困难即红利 有梦就去追 困难即红利以前刷帖子的时候,看到过这么一个问题:“放弃自己的梦想是怎样的一种体验?” ...
云浮小本钱创业小生意实体项目,...               *凡转载本微公众号文章,必须注明出处“云浮人社”,否则视为抄袭!    ...
创业板开通条件,创业板的利弊有...   “壳资源”炒作是神马?      “壳资源”炒作是a股市场的独特风景,也是a股市场的一大悲哀。一...