zoukankan      html  css  js  c++  java
  • RxSwift 系列(二)

    前言

    Subject是一个代理,它既是Observer,也是Observable。因为它是一个Observer,它可以订阅一个或多个Observable;因为它是一个Observable,它又可以被其他的Observer订阅。它可以传递/转发作为Observer收到的值,也可以主动发射值。

    SubjectRxSwift中的实现有四种:

    • PublishSubject
    • ReplaySubject
    • BehaviorSubject
    • Variable

    PublishSubject

    代理
    我们先以PublishSubject为例来解释Subject是一个代理的含义。

    let subject = PublishSubject<Int>()
    subject.subscribe({ (event) in
        print("Event:(event)")
    })
        
    subject.onNext(1)
    subject.onNext(2)
    subject.onCompleted()

    Subject作为一个Observable提供了subscribe等方法。在订阅之后,我们调用了onNext(),向Observer发射了12,以及onCompleted()。打印结果和我们预期的是一样的。

    Event:next(1)
    Event:next(2)
    Event:completed

    我们可以调用Subjecton系列方法主动给Observer发送值。

    Subject可以作为代理转发订阅到的结果。例如:

    let subject = PublishSubject<Int>()
    subject.subscribe({ (event) in
        print("Event:(event)")
    })
        
    let reveseSubject = Observable<Int>.create({ (observer) -> Disposable in
        observer.onNext(1)
        observer.onNext(2)
        observer.onCompleted()
            
        return Disposables.create()
    })
        
    reveseSubject.subscribe(subject)

    subject订阅了reveseSubject,并将结果转发给了Observer

    注意:Observer订阅 subject时不会收到订阅之前subject的值。

    let subject = PublishSubject<Int>()
    subject.onNext(0)
    subject.subscribe({ (event) in
        print("Event:(event)")
    })
        
    subject.onNext(1)
    subject.onNext(2)
    subject.onCompleted()

    上述代码结果为:

    Event:next(1)
    Event:next(2)
    Event:completed

    observer无法接收到0这个值。

    ReplaySubject

    ReplaySubjectPublishSubject不同的是,Observer有可能接收到订阅之前的值。

    let subject = ReplaySubject<Int>.create(bufferSize: 1)
        
        subject.onNext(0)
        subject.subscribe({ (event) in
            print("Event:(event)")
        })
        
        subject.onNext(1)
        subject.onNext(2)
        subject.onCompleted()

    上述代码结果为:

    Event:next(0)
    Event:next(1)
    Event:next(2)
    Event:completed

    ReplaySubject具有重放(replay)的功能,replay的个数可以通过参数指定。我们可以将其理解为缓存的效果。

    一般我们使用ReplaySubject的时候,都是先发射,后订阅,然后通过指定缓存的大小,可以获取对应的值。(注意:不考虑Error和Completed)。

    let subject = ReplaySubject<Int>.create(bufferSize: 1)
        
    subject.onNext(0)
    subject.onNext(1)
    subject.onNext(2)
    subject.onCompleted()
        
    subject.subscribe({ (event) in
        print("Event:(event)")
    })

    上述代码,我们指定了bufferSize等于1,所以只缓存了最新的值,打印结果:

    Event:next(2)
    Event:completed

    当我们需要缓存所有值的时候,可以调用createUnbounded()方法。

    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有一点好处,我们可以确定当Observer订阅时,至少可以收到最新的一个值。

    Variable

    VariableBehaviorSubject又很相似,VariableBehaviorSubject的一个封装,同样具备了缓存最新值和提供默认值的能力。但是Variable没有on系列方法,只提供了value属性。
    直接对value进行set等同于调用了onNext()方法。

    这表明了Variable不会发射error也不会发射completed

    Variable被销毁的时候会调用发射completedObserver

    在订阅Variable的时候,我们无法直接调用subscribe方法,需要先调用asObservable()方法。

    let variable = Variable<Int>(1)
    variable.asObservable().subscribe({ (event) in
        print("Event:(event)")
    })
    variable.value = 2

    上述结果为:

    Event:next(1)
    Event:next(2)
    Event:completed

    Variable可以用来储存数据,因为我们可以拥有valuegetset方法。比如:

    let variable = Variable(1)
    print("Value: (variable.value)")
    variable.value = 2
    print("Value: (variable.value)")

    打印结果为:

    Value: 1
    Value: 2

    这是BehaviorSubject不具备的。

  • 相关阅读:
    实验2实验报告
    实验1实验报告
    汇编实验九
    汇编实验5
    汇编实验四
    汇编实验三
    汇编实验二
    汇编实验一
    汇编第一章
    浅谈webpack4.0 性能优化
  • 原文地址:https://www.cnblogs.com/yujihaia/p/7425846.html
Copyright © 2011-2022 走看看