RxSwift学习-20-RxSwift中场景序列使用

401 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第23天,点击查看活动详情

  • 本文主要介绍RxSwift中的一些场景序列的使用

之前我们介绍过关于序列的创建的一些工厂方法 RxSwift学习-04-序列的创建,订阅和销毁,那么对于观察者我们也有一些类似的方法

1. Binder

Binder是我们观察者的一种,通常会响应我们的on方法,执行闭包的回调。

self.textFiled.rx.text

            .bind(to: self.label.rx.text)

            .disposed(by: disposeBag)

我们在RxCocoa中封装了大量的binder<T>类型

image.png

看下Binder的定义

image.png

遵循我们的ObserverType协议因此可以执行on方法,这里相比较平常的观察者有3点:

  1. 不会绑定错误事件,只会打印
  2. 确保绑定都是在给定 Scheduler 上执行(默认 MainScheduler
  3. 没有完成事件,不会处理完成事件

因此适合处理我们的一些UI的值,和一些点击事件

image.png

我们自己绑定序列

let observable = Observable<Bool>.create { (ob) -> Disposable in

            ob.onNext(true)

            ob.onError(NSError.init(domain: "NetworkError", code: 400, userInfo: nil))

            ob.onCompleted()

            return Disposables.create()

            }.observeOn(ConcurrentDispatchQueueScheduler(queue: DispatchQueue.global()))

        observable.bind(to: observer).disposed(by: self.disposeBag)

2. Single

看下Single的定义

image.png 不像Observable可以发出多个元素,它要么只能发出一个元素,成功或者错误。

let singleOB = Single<Any>.create { (single) -> Disposable in

            print("singleOB 是否共享")

            single(.success("success"))

            single(.success(NSError.init(domain: "NetworkError", code: 400, userInfo: nil)))

            return Disposables.create()

        }

        

        singleOB.subscribe { (reslut) in

            print("订阅:\(reslut)")

            }.disposed(by: disposeBag)

        

image.png

可以发现发送一个元素后序列就结束了,无法在发送事件

image.png

对于一些初始化也是只有一个元素

image.png

3. Completable

看下Completable的 定义 image.png

可以发现该序列没有任何元素,只能发送completeerror事件

let completableOB = Completable.create { (completable) -> Disposable in

            completable(.completed)

            completable(.error(NSError.init(domain: "NetworkError", code: 400, userInfo: nil)))

            return Disposables.create()

        }

        

        completableOB.subscribe { (reslut) in

            print("订阅:\(reslut)")

            }.disposed(by: disposeBag)

只订阅到了complete

image.png Completable 适用于那种你只关心任务是否完成,而不需要在意任务返回值的情况。它和 Observable<Void> 有点相似。

4. Maybe

MaybeObservable的另外一个版本。它介于SingleCompletable 之间,它要么只能发出一个元素,要么产生一个completed事件,要么产生一个error事件。

image.png

类似我们Single和Completable的集合

let maybeOB = Maybe<Any>.create { (maybe) -> Disposable in

            print("maybe 是否共享")

            maybe(.success("success"))

            maybe(.completed)

            maybe(.error(NSError.init(domain: "NetworkError", code: 400, userInfo: nil)))

            return Disposables.create()

        }

       

        maybeOB.subscribe { (reslut) in

            print("订阅:\(reslut)")

            }.disposed(by: disposeBag)

        

        maybeOB.subscribe { (reslut) in

            print("订阅:\(reslut)")

            }.disposed(by: disposeBag)

打印结果

image.png

如果你遇到那种可能需要发出一个元素,又可能不需要发出时,就可以使用 Maybe。

5. ControlEvent

专门用于描述UI控件所产生的事件,它具有以下特征

  • 不会产生 error 事件
  • 一定在 MainScheduler 订阅(主线程订阅)
  • 一定在 MainScheduler 监听(主线程监听)
  • 会共享附加作用

image.png

let controlEventOB = self.btn.rx.controlEvent(.touchUpInside)


        controlEventOB.subscribe { (reslut) in

                print("订阅:\(reslut) \n \(Thread.current)")

            }.disposed(by: disposeBag)


        controlEventOB.subscribe { (reslut) in

                print("订阅:\(reslut) \n \(Thread.current)")

            }.disposed(by: self.disposeBag)

打印结果都订阅到了

6. Driver

Driver 是一个特意准备的特征序列。它主要是为了简化UI 层的代码。不过如果你遇到的序列具有以下特征,你也可以使用它:

  • 不会产生 error 事件
  • 一定在 MainScheduler 监听(主线程监听)
  • 会共享附加作用
    let ob = Observable.just("hello").asDriver(onErrorJustReturn: "error")
    
// 绑定到label上面
        ob.drive(self.label.rx.text)

            .disposed(by: disposeBag)
// 绑定到button上面
        ob .drive(self.btn.rx.title())

            .disposed(by: disposeBag)

7. Signal

Signal Driver 相似,唯一的区别是,Driver 会对新观察者回放(重新发送)上一个元素,而 Signal 不会对新观察者回放上一个元素。

let single = Observable.just("hello").asSignal(onErrorJustReturn: "error")
// 绑定到label上面
        single.emit(to:self.label.rx.text)

            .disposed(by: disposeBag)
// 绑定到button上面
        single.emit(to:self.btn.rx.title())

            .disposed(by: disposeBag)