RxSwift - 操作符

916 阅读3分钟

RxSwift篇章

以下内容来自官方文档

一:Transforming Observables

1.map

定义:transform the items emitted by an Observable by applying a function to each item

  • map传入函数作用于可观察序列发出的元素.

        let mapOb = Observable.of(1, 2, 3)
        mapOb.map { (number) -> Int in
            return number * 2
        }
        .subscribe {
            print($0)
        }
        .disposed(by: disposeBag)

2.flatMap

定义:transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable

  • FlatMap操作符通过对源Observable发出的每个条目应用一个指定的函数来转换一个Observable,这个Observable可响应订阅.即:FlatMap合并了这些Observable可观察到的结果,将这些合并后的结果作为它自己的序列发出。

  • 这个方法是有用的,例如: 序列中 具有可观察到的成员或以其他方式转换成可见的,这样就可以创建一个新的可观察对象,它发出由这些项目的子可观察对象发出的项目的完整集合。

struct PLPlayer {
    let score: BehaviorSubject<Int>
    init(score: Int) {
        self.score = BehaviorSubject(value: score)
    }
}
//flatMap 
        let boy  = PLPlayer(score: 100)
        let girl = PLPlayer(score: 90)
        let player = BehaviorSubject(value: boy)

        player.asObservable()
            .flatMap { $0.score.asObservable() }
            .subscribe(
                onNext: { print($0) }
        )
            .disposed(by: disposeBag)
        
        boy.score.onNext(60)
        player.onNext(girl)
        boy.score.onNext(50)
        boy.score.onNext(40)
        girl.score.onNext(10)
        girl.score.onNext(0)

3.scan

定义: apply a function to each item emitted by an Observable, sequentially, and emit each successive value

  • 从初始就带有一个默认值开始,然后对可观察序列发出的每个元素应用累加器闭包,并以单个元素可观察序列的形式返回每个中间结果.

       Observable.of(10, 100, 1000)
            .scan(1) { aggregateValue, newValue in
                aggregateValue + newValue
            }
       .subscribe(onNext: { print($0) })
       .disposed(by: disposeBag)

二:Filtering Observables

1.filter

定义: emit only those items from an Observable that pass a predicate test *控制序列只发出满足条件的信号.

        Observable.of (1, 2, 3, 4, 5)
            .filter { $0 % 2 == 0}
            .subscribe { (event) in
                print(event)
            }
            .disposed(by: disposeBag)

2.distinctUntilChanged

定义: suppress duplicate items emitted by an Observable

  • 禁止序列发出重复的信号.
        Observable.of("1", "2", "2", "3")
            .distinctUntilChanged()
            .subscribe(onNext: {
                print($0)
            })
            .disposed(by: disposeBag)

3.elementAt

定义: emit only item n emitted by an Observable

  • 在源可观察对象发出的项序列中提取位于指定索引位置的项,并将该项作为其自身的唯一发射发出。
        Observable.of("1", "2", "3", "4")
            .elementAt(2)
            .subscribe(onNext: {
                print($0)
            })
            .disposed(by: disposeBag)

4.single

  • 只发出可观察序列发出的第一个元素(或满足条件的第一个元素)。如果可观察序列发出多个元素,将抛出一个错误。
        Observable.of("A", "B")
            .single().subscribe { (event) in
                print(event)
            }
            .disposed(by: disposeBag)

        Observable.of("A", "B", "C")
            .single { $0 == "B" }
            .subscribe { (event) in
                print(event)
            }
            .disposed(by: disposeBag)

5.take

定义: emit only the first n items emitted by an Observable

  • 控制一个Observable只发出前n个条目
        Observable.of("A", "B", "C")
            .take(2)
            .subscribe(onNext: {
                print($0)
            })
            .disposed(by: disposeBag)

6.takeLast

定义: emit only the final n items emitted by an Observable

  • 控制一个Observable只发出后n个条目
        Observable.of("A", "B", "C")
            .takeLast(2).subscribe(onNext: {
                print($0)
            })
            .disposed(by: disposeBag)

7.takeWhile

定义: mirror items emitted by an Observable until a specified condition becomes false

  • 只要指定条件的值为true,就从可观察序列的开始依次发出元素,直到条件false结束.
        Observable.of (1, 2, 3, 4, 5)
            .takeWhile { $0 < 3 }
            .subscribe(onNext: {
                print($0)
            })
            .disposed(by: disposeBag)

8.takeUntil

定义: discard any items emitted by an Observable after a second Observable emits an item or terminates

  • 序列发出信号,直到第二个观察对象(referenceSequence)发出一个项目或终止后,序列结束.
        let sourceSequence = PublishSubject<String>()
        let referenceSequence = PublishSubject<String>()
        sourceSequence
            .takeUntil(referenceSequence)
            .subscribe { print($0) }
            .disposed(by: disposeBag)

        sourceSequence.onNext("A")
        sourceSequence.onNext("B")
        referenceSequence.onNext("C") // 条件一出来,就结束...下面不走了
        sourceSequence.onNext("D")
        sourceSequence.onNext("E")

9.skip

定义: suppress the first n items emitted by an Observable

  • 禁止序列发出前n个项目
        Observable.of(1, 2, 3, 4, 5, 6)
        .skip(2)
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)

10.skipUntil

定义: discard items emitted by an Observable until a second Observable emits an item

  • 阻止序列发出项目,直到第二个观察对象(referenceSeq)发出一个项目.
           let sourceSeq = PublishSubject<String>()
        let referenceSeq = PublishSubject<String>()
        sourceSeq
            .skipUntil(referenceSeq)
            .subscribe { print($0) }
            .disposed(by: disposeBag)

        // 条件不出来,下面就不执行
        sourceSeq.onNext("A")
        sourceSeq.onNext("B")
        referenceSeq.onNext("C") // 条件一出来,就结束...下面就执行
        sourceSeq.onNext("D")
        sourceSeq.onNext("E")

三:Combining Observables

1.startWith

定义: emit a specified sequence of items before beginning to emit the items from the source Observable

  • 在开始从可观察源发出元素之前,发出指定的元素序列

        Observable.of("1","2")
            .startWith("A")
            .startWith("a", "b")
            .subscribe(onNext: {
                print($0)
            })
            .disposed(by: disposeBag)
    结果: abA12

2.merge

定义: combine multiple Observables into one by merging their emissions

  • 将源可观察序列中的元素(序列)组合成一个新的可观察序列,订阅后,可响应每个序列发出信号.

        let subject1 = PublishSubject<String>()
        let subject2 = PublishSubject<String>()
        Observable.of(subject1, subject2)
        .merge()
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
        
        subject1.onNext("A")
        subject2.onNext("B")
        subject1.onNext("C")
    结果: ABC  任何一个响应都会勾起新序列响应.

3.zip

定义: 通过指定的函数将多个可观测项的排放组合在一起,并根据该函数的结果为每个组合排放单个项

  • 将源可观测序列组合成一个新的可观测序列.
  • 从新测序列中处理原序列的组合信号,这个组合信号为依次取出每个源可观测序列的元素.组合信号的个数与发出最少项的源可观察对象发出的项数相同.
  • 新序列传入的函数作用于这个组合信号,控制最终发出的信号结果.

            let stringSubject = PublishSubject<String>()
        let intSubject = PublishSubject<Int>()

        Observable.zip(stringSubject, intSubject) { stringElement, intElement in
                "\(stringElement) \(intElement)"
            }
            .subscribe(onNext: { print($0) })
            .disposed(by: disposeBag)

        stringSubject.onNext("A")
        stringSubject.onNext("B") // 到这里存储了 A B 但是不会响应(除非: 另一个响应);

        intSubject.onNext(1) // 勾出一个
        intSubject.onNext(2) // 勾出另一个
        stringSubject.onNext("C") // 存一个
        intSubject.onNext(3) // 勾出一个
        // 说白了: 只有两个序列同时有值的时候才会响应,否则存值.
        //结果: 输出结果与zip()函数结果一致.
//        A 1
//        B 2
//        C 3

4.combineLatest

定义:当一个项目由两个可观察对象之一发出时,通过指定的函数组合每个可观察对象发出的最新项目,并基于该函数的结果发出项目

  • 将源可观察序列组合成一个新的可观察序列.
  • 从新测序列中处理原序列的组合信号,这个组合信号为依次取出每个源可观测序列的最新元素,前提条件为每个源发出至少一项.
  • 新序列传入的函数作用于这个组合信号,控制最终发出的信号结果.

          let stringSub = PublishSubject<String>()
        let intSub = PublishSubject<Int>()
        Observable.combineLatest(stringSub, intSub) { strElement, intElement in
                "\(strElement) \(intElement)"
            }
            .subscribe(onNext: { print($0) })
            .disposed(by: disposeBag)

        stringSub.onNext("A") // 存一个 A
        stringSub.onNext("B") // 存一个覆盖 - 和zip不一样
        intSub.onNext(1)      // 发现strOB也有B 响应 B 1
        intSub.onNext(2)      // 覆盖1 -> 2 发现strOB 有值B 响应 B 2
        stringSub.onNext("XY") // 覆盖B -> Cooci 发现intOB 有值2 响应 XY 2
        //打印结果:
//        B 1
//        B 2
//        XY 2

5.switchLatest

定义: 将发出可观察的一个可观察对象转换为单个可观察对象,该可观察对象发出最近发出的那些可观察对象发出的项

        let switchLatestSub1 = BehaviorSubject(value: "A")
        let switchLatestSub2 = BehaviorSubject(value: "1")
        let switchLatestSub  = BehaviorSubject(value: switchLatestSub1)// 选择了 switchLatestSub1 就不会监听 switchLatestSub2

        switchLatestSub.asObservable()
            .switchLatest()
            .subscribe(onNext: { print($0) })
            .disposed(by: disposeBag)

        switchLatestSub1.onNext("B")
        switchLatestSub1.onNext("C")
        switchLatestSub2.onNext("2")
        switchLatestSub2.onNext("3") // 2-3都会不会监听,但是默认保存由 2覆盖1 3覆盖2
        switchLatestSub.onNext(switchLatestSub2) // 切换到 switchLatestSub2
        switchLatestSub1.onNext("D")
        switchLatestSub1.onNext("XY") // 原理同上面 下面如果再次切换到 switchLatestSub1会打印出 XY
        switchLatestSub.onNext(switchLatestSub1)
        //打印结果:
//        A
//        B
//        C
//        3
//        XY

四:Mathematical and Aggregate Operators

1.reduce

定义: apply a function to each item emitted by an Observable, sequentially, and emit the final value

  • 从一个设置的初始化值开始,然后对一个可观察序列发出的所有元素应用累加器闭包,并以单个元素可观察序列的形式返回聚合结果
Observable.of(10, 100, 1000)
            .reduce(1, accumulator: +)
            .subscribe(onNext: { print($0) })
            .disposed(by: disposeBag)

2.concat

定义: emit the emissions from two or more Observables without interleaving them

  • 将多个观察对象的输出连接起来,使它们的行为类似于单个观察对象,第一个观察对象发出的所有项都先于第二个观察对象发出的任何项(如果有两个以上,则以此类推)。
        let subject1 = BehaviorSubject(value: "A")
        let subject2 = BehaviorSubject(value: "1")
        //
        let subjectsSubject = BehaviorSubject(value: subject1)
        subjectsSubject.asObservable()
            .concat()
            .subscribe { print($0) }
            .disposed(by: disposeBag)
        subject1.onNext("B")
        subject1.onNext("C")
        //切换 subject2
        subjectsSubject.onNext(subject2)
        subject2.onNext("打印不出来")
        subject2.onNext("2")
        subject1.onCompleted() // 必须要等subject1 完成了才能订阅到!
        subject2.onNext("3")

五:to Convert Observables

定义: convert an Observable into another object or data structure

1.toArray

  • 将源序列信号组合为新序列的一个数组信号,源序列终止,新序列发出这个数组信号.

        Observable.range(start: 1, count: 10)
        .toArray()
        .subscribe {
            print($0)
            
        }
        .disposed(by: disposeBag)