BehaviorSubject BehaviorSubject 是 Subject 的一个变种,他的特点是会存储当前值, const subject = new rxjs.Subject(); subject.subscribe ((next => { console.log(next); })); // 打开下面的注释才会输出结果 // subject.next(1); 而 BehaviorSubject 一旦 subscribe const subject = new rxjs.BehaviorSubject(0); // 会输出 0 subject.subscribe((next => { console.log(next observerB); // 根据传入 n 的不同 // "B next: 2" // "B next: 3" },3000) ReplaySubject(1) 不等同于 BehaviorSubject ,BehaviorSubject 在建立时就会有起始值,比如 BehaviorSubject(0) 起始值就是 0,BehaviorSubject 是代表着状态而 ReplaySubject 只是事件的重放而已
PublishSubject<Integer> publishSubject = PublishSubject.create(); BehaviorSubject BehaviorSubject会首先向他的订阅者发送截至订阅前最新的一个数据对象 BehaviorSubject<Integer> behaviorSubject = BehaviorSubject.create(0); 我们创建了一个能发射整形(Integer)的BehaviorSubject observerTest() { PublishSubject<Integer> publishSubject = PublishSubject.create(); BehaviorSubject <Integer> behaviorSubject = BehaviorSubject.create(0); ReplaySubject<Integer> replaySubject = start -1 # 如果前面没有发送数据, 此处会显示 0 1 2 3 onCompleted BehaviorSubject end ==============================
"); subject.onNext("behaviorSubject3"); 执行结果: behaviorSubject:behaviorSubject1 behaviorSubject :behaviorSubject2 behaviorSubject:behaviorSubject3 在这里,behaviorSubject1是默认值。 BehaviorSubject<String> subject = BehaviorSubject.createDefault("behaviorSubject1"); subject.onNext "); subject.onNext("behaviorSubject4"); 执行结果: behaviorSubject:behaviorSubject2 behaviorSubject :behaviorSubject3 behaviorSubject:behaviorSubject4 这次丢弃了默认值,而发射behaviorSubject2。
BehaviorSubject BehaviorSubject 能够保存当前值,当有新的观察者订阅时,就会立即从BehaviorSubject 接收到当前值。 下面这段代码,初始值为0,尽管第二个观察者是在 2 发送出去之后订阅的,但是BehaviorSubject 保存了当前值,在第二个观察者订阅时立即从BehaviorSubject 接收到了当前值 2。 var subject = new Rx.BehaviorSubject(0); subject.subscribe({ next: (v) => console.log('observerA: ReplaySubject ReplaySubject 和 BehaviorSubject 相似,ReplaySubject 能够保存指定个数的数据,当有新的观察者订阅时,就会从 ReplaySubject
BehaviorSubject Subject可能存在的问题是,观察者将仅收到订阅主题后发出的值。 在上一个示例中,第二个发射器未接收到值0、1和2。 对于这种情况,可以使用BehaviorSubject。BehaviorSubject保留其发出的最后一个值的内存。订阅后,观察者立即接收到最后发出的值。 import { BehaviorSubject } from 'rxjs'; const behaviorSubject = new BehaviorSubject(0); for (let i = 1; i < 60; i += 1) { setTimeout(() => { behaviorSubject.next(i); }, i * 1000); } console.log 这是因为BehaviorSubject始终需要当前值。 ReplaySubject ReplaySubjects与BehaviorSubjects非常相似。
Subject在RxSwift中的实现有四种: PublishSubject ReplaySubject BehaviorSubject Variable PublishSubject 代理 我们先以 ReplaySubject BehaviorSubject BehaviorSubject类似于ReplaySubject具有缓存能力,但是略有不同。 只缓存一个最新值,类似ReplaySubject.create(bufferSize: 1) 需要提供默认值 let behaviorSubject = BehaviorSubject<Int>(value : 1) behaviorSubject.subscribe({ (event) in print("Event:\(event)") }) 打印结果为: Event:next(1) 使用BehaviorSubject Variable Variable和BehaviorSubject又很相似,Variable是BehaviorSubject的一个封装,同样具备了缓存最新值和提供默认值的能力。
BehaviorSubject:有一个初始值,重复发送或者是发送最新的事件给订阅者。 Variable:相当于一个BehaviorSubject的封装,它会保存当前值做为自身的一个状态,发送当前的状态给新的订阅者。 BehaviorSubject跟PublishSubject相似,只是它会发送最近的一个next事件给新的订阅者。 如上面的Marble diagram: 第一条线是一个BehaviorSubject,第二、第三条是订阅者,向上的箭头表示订阅者订阅Subject,向下的箭头表示Subject发送事件。 event) } example("BehaviorSubject") { let subject = BehaviorSubject(value: "1") let disposeBag
RxJava 提供了 4种 Subject AsyncSubject BehaviorSubject PublishSubject ReplaySubject 我们重点说BehaviorSubject, compose 如果让我们的所有Observable都自己新建一个BehaviorSubject,然后去调用takeUtil,然后在activity或者Fragment的生命周期回调中调用 BehaviorSubject.onNext 它的一个常规操作就是用来简化重复代码,比如SubscribeOn,ObserverOn 这样的公式代码, 当然我们在我们这里也可以用它,所以我们自然想到新建一个RxLifeCycleActivity基类,然后新建一个BehaviorSubject 对象,新建一个bind方法,供子类调用绑定生命周期,然后在OnDestory中调用BehaviorSubject的onNext方法 ? rxlifecycle event callback.png 然后新建一个新的方法bindUntil,第二个参数是想要终止的条件事件,我们对BehaviorSubject接收到的数据进行一次filter
BehaviorSubject 当有observer在订阅一个BehaviorSubject的时候,它首先将会收到Observable上最近发送一个信号(或者是默认值),接着才会收到Observable Variable Variable是BehaviorSubject的封装,它和BehaviorSubject不同之处在于,不能向Variable发送.Complete和.Error,它会在生命周期结束被释放的时候自动发送
要实现这个功能,我们就需要使用 BehaviorSubject。 BehaviorSubject 跟 Subject 最大的不同就是 BehaviorSubject 是用来保存当前最新的值,而不是单纯的发送事件。 BehaviorSubject 会记住最近一次发送的值,并把该值作为当前值保存在内部的属性中。 下面我们来使用 BehaviorSubject 重写上面的示例: import { BehaviorSubject } from "rxjs"; const subject = new BehaviorSubject 在创建BehaviorSubject 对象时,是设置初始值,它用于表示 Subject 对象当前的状态,而 ReplaySubject 只是事件的重放。
也有一些特殊的 Subject:BehaviorSubject,ReplaySubject 和 AsyncSubject。 # BehaviorSubject BehaviorSubject 是 Subject 的变体之一,具有“当前值”的概念。 它存储发送给其消费者最新的值,并且每当有新的 Observer 订阅时,它将立即接收来自 BehaviorSubject 的 “当前值”。 BehaviorSubject 对于表示 “随时间变化的值” 很有用。如,生日的事件流是一个 Subject,但一个人的年龄是 BehaviorSubject。 import { BehaviorSubject } from 'rxjs'; const subject = new BehaviorSubject(0); // 初始值为 0 subject.subscribe
RxSwift Subject共分为AsyncSubject、BehaviorSubject、PublishSubject、ReplaySubject。 observerA: onCompleted observerB: onCompleted observerC: onCompleted observerD: 3 observerD: onCompleted BehaviorSubject 当观察者订阅BehaviorSubject时,它开始发射原始Observable最近发射的数据,然后继续发射其它任何来自原始Observable的数据。 let disposeBag = DisposeBag() let subject = BehaviorSubject<Int>(value: 0) subject.onNext(1) subject.subscribe
ionic g provider setting-data setting-data.ts: import {Injectable} from '@angular/core'; import {BehaviorSubject } from "rxjs/BehaviorSubject"; @Injectable() export class SettingDataProvider { // true: dark-theme // false: light-theme theme: BehaviorSubject<boolean>; constructor() { this.theme = new BehaviorSubject
console.log("observerB: " + value) //接受者B订阅消息,获取消息流中的数据 }); 这样两路接受者都能拿到发送的数据流: observerA:1 observerB:1 2/ BehaviorSubject BehaviorSubject 是 Subject 的一个衍生类,它将数据流中的最新值推送给接受者。 var subject = new Rx.BehaviorSubject(0); //声明一个 BehaviorSubject 对象 subject.next(1); //发送一个数据流 subject.next 每次接受者只会接受最新最送的那个消息: observerA:2 observerB:2 observerA:3 observerB:3 3/ ReplaySubject ReplaySubject 类似于 BehaviorSubject subject.next(5); subject.complete(); 输出: observerA: 5 observerB: 5 参考文档《PublishSubject,ReplaySubject,BehaviorSubject
所以 ReplaySubject 不可滥用且缓存区大小必须合理进行设置,必要时可手动进行释放管理 Variable 本身是对 BehaviorSubject 封装,创建时也必须设置一个默认值。 继承自 BehaviorSubject ,那么就能向订阅者发出上一个 event 与新的 event。 与 BehaviorSubject 不同的是,Variable还会把当前发出的值保存为自己的状态,同时在销毁时自动发送 .completed event,不需要也不能手动给 Variable 发送终结事件 PublishSubject打印结果 BehaviorSubject代码示例 let subject = BehaviorSubject(value: "first signal") BehaviorSubject打印结果 ReplaySubject代码示例 //设置缓存最近2个event let subject = ReplaySubject<String
方法二 使用 BehaviorSubject 优点:真正的发布订阅模式,当数据改变时,订阅者也能得到响应 service import { BehaviorSubject } from 'rxjs'; ... public messageSource = new BehaviorSubject<string>('Start'); changemessage(message: string): void
BehaviorSubject BehaviorSubject 是Subject的一个变种, 它有一个当前值的概念, 它会把它上一次发送给订阅者值保存起来, 一旦有新的Observer进行了订阅, 那这个 Observer马上就会从BehaviorSubject收到这个当前值. 也可以这样理解BehaviorSubject的特点: 它代表一个随时间变化的值, 例如, 生日的流就是Subject, 而一个人的年龄流就是BehaviorSubject. 每个订阅者都会从BehaviorSubject那里得到它推送出来的初始值和最新的值. 用例: 共享app状态. 例子 behavior-subject.ts: import { BehaviorSubject } from "rxjs/BehaviorSubject"; const subject = new
而Subject有很多种类:子类有PublishSubject、BehaviorSubject、ReplaySubject、AsyncSubject、SerializedSubject。 具体每种的区别可以看:RxJava中常见的几种Subject 这里我们主要讲解BehaviorSubject。 大意是BehaviorSubject会发送离订阅最近的上一个值,没有上一个值的时候会发送默认值(如果有的话)。 ? BehaviorSubject subject = BehaviorSubject.create(); //把Observable这块方面通过方法分享出去,但是又不想整个Subject都分享出去 private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create(); @Override
Angular 开发的内容 - 服务 Service 写法使用 我们新建一个数据管理的 javascript 文件: // src/service/data-manage.js import { BehaviorSubject } from 'rxjs'; // 引入 BehaviorSubject; 它保存了发送给消费者的最新值 let userInfoSubject$ = new BehaviorSubject({});
先来看看如何实现粘性事件的功能,我们熟知的Subject有四种:AsyncSubject,BehaviorSubject,PublishSubject,ReplaySubject,我们先一一解释下这些东西 BehaviorSubject:发射原始Observable最近发射的数据 ? PublishSubject:会把在订阅发生的时间点之后来自原始Observable的数据发射给观察者 ? 从上面的介绍可以看出,AsyncSubject显然不合适,PublishSubject看起来也不太合适,因为它不会发送订阅之前的消息,ReplaySubject和BehaviorSubject都能发送订阅之前的消息 BehaviorSubject它只会存储最近的一个事件,这样不会有内存隐患,但是这个特性本身也会存在隐患。比如,在发送事件A和接收事件A之间的某个时间点,如果又发送了事件B 那么,事件A就会被抛弃。 因此,BehaviorSubject也不是一个好的选择。 其实,以上四个Subject都不是最好的选择,最终还是决定自己缓存事件,并在合适的时机清除历。