varHarrie / varharrie.github.io

:blue_book: Personal blog site based on github issues.
https://varharrie.github.io
MIT License
3.66k stars 548 forks source link

[Rxjs] Subject、BehaviorSubject、ReplaySubject、AsyncSubject #23

Open varHarrie opened 6 years ago

varHarrie commented 6 years ago

Subject、BehaviorSubject、ReplaySubject、AsyncSubject

Subject

SubjectObservable(可观察对象),每一个Subject都有可以被subscribe(订阅),但不会创建新的执行环境,只会把新的Observer注册到内部维护着的Observer清单

SubjectObserver(观察者),是一个由next()error()complete()方法组成的对象,可以subscribe(订阅)一个Observable,并从其中接受到推送的值。

每次Subject接收到值时,都遍历Observer清单,并推送该值。

BehaviorSubject

BehaviorSubjectSubject的子类,拥有初始值,并且总是保存着一个最新值,一旦被订阅立即向订阅者发送最新值

const subject = new Rx.BehaviorSubject(0) // 初始值为0

subject.subscribe((value) => console.log('A value: ', value))

subject.next(1)
// A value: 0
// A value: 1
subject.next(2)
// A value: 2
// B value: 2

subject.subscribe((value) => console.log('B value: ', value))

subject.next(3)
// A value: 3
// B value: 3

ReplaySubject

ReplaySubject也是Subject的子类,被订阅时立即向订阅者推送最新指定数量的值

const subject = new Rx.ReplaySubject(2) // 回放2个

subject.subscribe((value) => console.log('A value: ', value))

subject.next(1)
// A value: 1
subject.next(2)
// A value: 2
subject.next(3)
// A value: 3

subject.subscribe((value) => console.log('B value: ', value))
// B value: 2
// B value: 3

subject.next(4)
// A value: 4
// B value: 4

AsyncSubject

AsyncSubject也是Subject的子类,仅会在complete()之后,向订阅者推送最后一个值

const subject = new Rx.AsyncSubject()

subject.subscribe((value) => console.log('A value: ', value))

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

subject.subscribe((value) => console.log('B value: ', value))

subject.next(3)
subject.complete()
// A value: 3
// B value: 3

multicast、refCount、publish、share

在开头我们提到Subject就是一个Obserable,但新的订阅者会共用同一个执行环境:

const source = Rx.Observable.interval(1000)
                                .take(3)
const subject = new Rx.Subject()

subject.subscribe((value) => console.log('A value: ', value))

source.subscribe(subject)

setTimeot(() => {
  subject.subscribe((value) => console.log('B value: ', value))
}, 1000)

// A value: 0
// A value: 1
// B value: 1
// A value: 2
// B value: 2

B在1秒钟之后订阅,所以不会接受到第一个值0

参考资料

30 天精通 RxJS