RxSwift:操作符

来源:互联网 发布:西南交通大学网络缴费 编辑:程序博客网 时间:2024/06/15 04:56

RxSwift:操作符


绑定操作

  • startWith

    发出指定序列中的元素之前,先发出指定序列中的元素。

    这里写图片描述

    let disposeBag = DisposeBag()Observable.of("OC", "C", "Java", "C++")                  .startWith("1")                  .startWith("2")                  .startWith("3", "A", "B")                  .subscribe(onNext: { print($0) })                  .addDisposableTo(disposeBag)输出:3AB21OCCJavaC++
  • merge

    将多个Observable合并成一个Observable,按照时间顺序发出对应的事件。

    这里写图片描述

    let disposeBag = DisposeBag()let subject1 = PublishSubject<String>()let subject2 = PublishSubject<String>()        Observable.of(subject1, subject2)                  .merge()                  .subscribe(onNext: { print($0) })                  .addDisposableTo(disposeBag)subject1.onNext("A")subject1.onNext("B")subject2.onNext("1")subject2.onNext("2")subject1.onNext("C")subject2.onNext("C")输出:AB12CC
  • zip

    将多个(最多8个)Observable合并成一个新的Observable。当有事件到达时,会在每个序列中对应的索引上对应的元素发出。

这里写图片描述

let disposeBag = DisposeBag()let stringSubject = PublishSubject<String>()let intSubject = PublishSubject<Int>()        Observable.zip(stringSubject, intSubject) { stringElement, intElement in    "\(stringElement) \(intElement)"    }.subscribe(onNext: { print($0)    }).addDisposableTo(disposeBag)stringSubject.onNext("A")stringSubject.onNext("B")        intSubject.onNext(1)        intSubject.onNext(2)        stringSubject.onNext("C")intSubject.onNext(3)输出:A 1B 2C 3
  • combineLatest

    将最多8个被观察序列合并为一个新的被观察序列,当有事件到达时,会将每个序列中的最新事件发出。

这里写图片描述

let disposeBag = DisposeBag()let stringSubject = PublishSubject<String>()let intSubject = PublishSubject<Int>()Observable.combineLatest(stringSubject, intSubject) { stringElement, intElement in "\(stringElement) \(intElement)"}.subscribe(onNext: { print($0) }) .addDisposableTo(disposeBag)stringSubject.onNext("A")stringSubject.onNext("B")intSubject.onNext(1)        intSubject.onNext(2)        stringSubject.onNext("C")输出:B 1B 2C 2
  • switchLatest

    将被监听的被观察者转换为另一个被观察者,从最近的被观察序列中发出元素。

这里写图片描述

let disposeBag = DisposeBag()let subject1 = BehaviorSubject(value: "1")let subject2 = BehaviorSubject(value: "A")let variable = Variable(subject1)variable.asObservable()        .switchLatest()        .subscribe(onNext: { print($0) })        .addDisposableTo(disposeBag)subject1.onNext("2")subject1.onNext("3")        variable.value = subject2        subject1.onNext("4")        subject2.onNext("B")输出:123AB

转换操作

  • map

    通过使用一个函数闭包将原来的Observable序列转换为一个新的Observable序列。

这里写图片描述

let disposeBag = DisposeBag()Observable.of(1, 2, 3)          .map { $0 * $0 }          .subscribe(onNext: { print($0) })          .addDisposableTo(disposeBag)输出:149
  • flatMap

    将一个Observable序列转换为另一个Observable序列,并且合并两个Observable序列。会按时间顺序接收两个序列发出的元素。

这里写图片描述

let disposeBag = DisposeBag()struct Player {    var score: Variable<Int>}let man = Player(score: Variable(80))let woman = Player(score: Variable(90))let player = Variable(man)player.asObservable()      .flatMap { $0.score.asObservable() }       .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)man.score.value = 85player.value = womanman.score.value = 95woman.score.value = 100输出:80859095100
  • flatMapLatest

    flatMapLatest同flatMap一样,也是将一个序列转换为另一个序列,flatMapLatest只会从最近的序列中发出事件。flatMapLatest = map + switchLatest

let disposeBag = DisposeBag()struct Player {    var score: Variable<Int>}let man = Player(score: Variable(80))let woman = Player(score: Variable(90))let player = Variable(man)player.asObservable()      .flatMapLatest { $0.score.asObservable() }       .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)man.score.value = 85player.value = womanman.score.value = 95woman.score.value = 100输出:808590100
  • scan

    scan就是提供一个初始化值,然后使用计算闭包不断将前一个元素和后一个元素进行处理,并将处理结果作为单个元素的Observable序列返回。

这里写图片描述

let disposeBag = DisposeBag()Observable.of(10, 100, 1000)          .scan(1) { aggregateValue, newValue in            aggregateValue + newValue            }          .subscribe(onNext: { print($0) })          .addDisposableTo(disposeBag)输出:111111111

过滤和条件操作符

从Observable序列中挑选出发出的元素的操作。

  • filter

    在Observable序列中只发出满足过滤条件的事件。

这里写图片描述

let disposeBag = DisposeBag()Observable.of(              "A", "B", "C",              "D", "A", "B",              "E", "D", "A")              .filter {                 $0 == "A"              }              .subscribe(onNext: { print($0) })              .addDisposableTo(disposeBag)输出:AAA
  • distinctUntilChanged

    禁止连续发出相同的事件。

这里写图片描述

let disposeBag = DisposeBag()Observable.of("A", "B", "A", "A", "A", "C", "A")          .distinctUntilChanged()          .subscribe(onNext: { print($0) })          .addDisposableTo(disposeBag)输出:ABACA
  • elementAt

    Observable序列只发出在指定位置的事件。

这里写图片描述

let disposeBag = DisposeBag()Observable.of("A", "B", "C", "D", "E", "F")          .elementAt(3)          .subscribe(onNext: { print($0) })          .addDisposableTo(disposeBag)输出:D
  • single

只发出一个事件,若发出多个事件或不发出事件,都会发出error错误。

let disposeBag = DisposeBag()Observable.of("A", "B", "C", "D", "E", "F")          .single()          .subscribe(onNext: { print($0) })          .addDisposableTo(disposeBag)输出:AReceived unhandled error: /Demo/RxSwift-master/RxExample/RxExample/iOS/AppDelegate.swift:412:application(_:didFinishLaunchingWithOptions:) -> Sequence contains more than one element.
let disposeBag = DisposeBag()Observable.of("A", "B", "C", "D", "E", "F")          .single { $0 == "D" }          .subscribe { print($0) }          .addDisposableTo(disposeBag)Observable.of("A", "B", "C", "D", "B", "E")          .single { $0 == "B" }          .subscribe { print($0) }        .addDisposableTo(disposeBag)Observable.of("A", "B", "C", "D", "E", "F")          .single { $0 == "H" }          .subscribe { print($0) }          .addDisposableTo(disposeBag)输出:next(D)completednext(B)error(Sequence contains more than one element.)error(Sequence doesn't contain any elements.)
  • take

    只处理前几个信号。

这里写图片描述

let disposeBag = DisposeBag()Observable.of("A", "B", "C", "D", "E", "F")          .take(3)          .subscribe(onNext: { print($0) })          .addDisposableTo(disposeBag)输出:ABC
  • takeLast

    只处理后几个信号。

这里写图片描述

let disposeBag = DisposeBag()Observable.of("A", "B", "C", "D", "E", "F")          .takeLast(3)          .subscribe(onNext: { print($0) })          .addDisposableTo(disposeBag)输出:DEF
  • takeWhile

    只处理满足条件的信号。

这里写图片描述

let disposeBag = DisposeBag()Observable.of(1, 2, 3, 4, 5, 6)          .takeWhile { $0 < 4 }          .subscribe(onNext: { print($0) })          .addDisposableTo(disposeBag)输出:123
  • takeUntil

    直到另一个Observable序列发出一个信号,则原序列终止。

这里写图片描述

let disposeBag = DisposeBag()let sourceSequence = PublishSubject<String>()let referenceSequence = PublishSubject<String>()sourceSequence.takeUntil(referenceSequence)              .subscribe { print($0) }              .addDisposableTo(disposeBag)sourceSequence.onNext("A")sourceSequence.onNext("B")sourceSequence.onNext("C")referenceSequence.onNext("1")sourceSequence.onNext("E")sourceSequence.onNext("F")sourceSequence.onNext("G")输出:next(A)next(B)next(C)completed
  • skip

    跳过前几个信号。

这里写图片描述

//跳过前两个事件let disposeBag = DisposeBag()Observable.of("A", "B", "C", "D", "E", "F")          .skip(2)          .subscribe(onNext: { print($0) })          .addDisposableTo(disposeBag)输出:CDEF
  • skipWhile

    跳过满足条件的事件,只要遇见不满足条件的事件,则该事件极其之后的事件(不管是否满足条件)都会发出。

这里写图片描述

let disposeBag = DisposeBag()Observable.of(1, 2, 3, 4, , 6)          .skipWhile { $0 < 4 }          .subscribe(onNext: { print($0) })          .addDisposableTo(disposeBag)输出:456
  • skipWhileWithIndex

    跳过索引满足条件的事件。

let disposeBag = DisposeBag()Observable.of("A", "B", "C", "D", "E", "F")          .skipWhileWithIndex { element, index in            index < 3            }          .subscribe(onNext: { print($0) })          .addDisposableTo(disposeBag)输出:DEF
  • skipUntil

    跳过另一个Observable序列发出事件之前的所有事件。

这里写图片描述

let disposeBag = DisposeBag()let sourceSequence = PublishSubject<String>()let referenceSequence = PublishSubject<String>()sourceSequence.skipUntil(referenceSequence)              .subscribe(onNext: { print($0) })              .addDisposableTo(disposeBag)sourceSequence.onNext("A")sourceSequence.onNext("B")sourceSequence.onNext("C")referenceSequence.onNext("1")sourceSequence.onNext("E")sourceSequence.onNext("F")sourceSequence.onNext("G")输出:EFG

数学和集合操作符

  • toArray

    将一个Observable序列转化为一个数组,并转换为单一的事件信号,然后结束。

这里写图片描述

let disposeBag = DisposeBag()Observable.range(start: 1, count: 10)          .toArray()          .subscribe { print($0) }          .addDisposableTo(disposeBag)输出:next([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])completed
  • reduce

    使用一个初始值和一个操作符,对Observable序列中的所有元素进行累计操作,并转换成单一事件信号。

这里写图片描述

let disposeBag = DisposeBag()Observable.of(10, 100, 1000)          .reduce(1, accumulator: +)          .subscribe(onNext: { print($0) })          .addDisposableTo(disposeBag)输出:1111
  • concat

    将两个序列合并成一个序列,当一个序列中的所有信号发送完成后,才后发送另一个序列中的信号。

这里写图片描述

let disposeBag = DisposeBag()let subject1 = BehaviorSubject(value: "A")let subject2 = BehaviorSubject(value: "1")let variable = Variable(subject1)variable.asObservable()        .concat()        .subscribe { print($0) }        .addDisposableTo(disposeBag)subject1.onNext("B")subject1.onNext("C")variable.value = subject2subject2.onNext("I would be ignored")subject2.onNext("2")subject1.onCompleted()subject2.onNext("3")输出:next(A)next(B)next(C)next(1)next(2)

连接操作符

Connectable Observable在订阅时不会发出事件消息,而是仅当调用它们的connec()方法时才会发出事件消息。这样就可以等待所有我们想要的订阅者都已经订阅了以后,再开始发出事件消息,这样能保证我们想要的所有订阅者都能接收到事件消息。其实也就是等大家都就位以后,开始发出消息。

  • publish

    将一个普通的Observable转换为一个Connectable Observable。

这里写图片描述

let intSequence = Observable<Int>.interval(1, scheduler: MainScheduler.instance).publish()_ = intSequence.subscribe(onNext: { print("Subscription 1:, Event: \($0)") })delay(2) { _ = intSequence.connect() }//把信号推迟2s发出delay(4) {        _ = intSequence            .subscribe(onNext: { print("Subscription 2:, Event: \($0)") })    }delay(6) {        _ = intSequence            .subscribe(onNext: { print("Subscription 3:, Event: \($0)") })    }输出:Subscription 1:, Event: 0Subscription 1:, Event: 1Subscription 1:, Event: 2Subscription 2:, Event: 2Subscription 1:, Event: 3Subscription 2:, Event: 3Subscription 1:, Event: 4Subscription 3:, Event: 4Subscription 2:, Event: 4...
  • replay

    将一个普通的sequence转换成一个connectable sequence,然后和replaySubject相似,能接收到订阅之前的事件消息。

这里写图片描述

let intSequence = Observable<Int>.interval(1, scheduler: MainScheduler.instance).replay(5)_ = intSequence.subscribe(onNext: { print("Subscription 1:, Event: \($0)") })delay(2) { _ = intSequence.connect() }delay(4) {        _ = intSequence            .subscribe(onNext: { print("Subscription 2:, Event: \($0)") })    }delay(8) {        _ = intSequence            .subscribe(onNext: { print("Subscription 3:, Event: \($0)") })    }输出:Subscription 1:, Event: 0Subscription 1:, Event: 1Subscription 2:, Event: 0Subscription 2:, Event: 1Subscription 1:, Event: 2Subscription 2:, Event: 2Subscription 1:, Event: 3Subscription 2:, Event: 3Subscription 1:, Event: 4Subscription 2:, Event: 4Subscription 1:, Event: 5Subscription 2:, Event: 5Subscription 3:, Event: 1Subscription 3:, Event: 2Subscription 3:, Event: 3Subscription 3:, Event: 4Subscription 3:, Event: 5Subscription 1:, Event: 6Subscription 3:, Event: 6Subscription 2:, Event: 6Subscription 1:, Event: 7Subscription 3:, Event: 7Subscription 2:, Event: 7Subscription 1:, Event: 8Subscription 3:, Event: 8Subscription 2:, Event: 8Subscription 1:, Event: 9Subscription 3:, Event: 9Subscription 2:, Event: 9Subscription 1:, Event: 10Subscription 3:, Event: 10Subscription 2:, Event: 10...
  • multicast

将普通的Observable序列转换为connectable sequence,通过指定的subject广播事件。

let subject = PublishSubject<Int>() _ = subject.subscribe(onNext: { print("Subject: \($0)") })let intSequence = Observable<Int>.interval(1, scheduler: MainScheduler.instance).multicast(subject) _ = intSequence.subscribe(onNext: { print("\tSubscription 1:, Event: \($0)") })delay(2) { _ = intSequence.connect() }delay(4) {        _ = intSequence            .subscribe(onNext: { print("\tSubscription 2:, Event: \($0)") })    }delay(6) {        _ = intSequence            .subscribe(onNext: { print("\tSubscription 3:, Event: \($0)") })    }输出:Subject: 0    Subscription 1:, Event: 0Subject: 1    Subscription 1:, Event: 1Subject: 2    Subscription 2:, Event: 2    Subscription 1:, Event: 2Subject: 3    Subscription 2:, Event: 3    Subscription 1:, Event: 3Subject: 4    Subscription 2:, Event: 4    Subscription 3:, Event: 4    Subscription 1:, Event: 4Subject: 5    Subscription 2:, Event: 5    Subscription 3:, Event: 5    Subscription 1:, Event: 5Subject: 6    Subscription 2:, Event: 6    Subscription 3:, Event: 6    Subscription 1:, Event: 6Subject: 7    Subscription 2:, Event: 7    Subscription 3:, Event: 7    Subscription 1:, Event: 7

错误处理

帮助从一个Observable的错误通知中恢复的运算符。

  • catchErrorJustReturn

    遇到Error事件时,输出一个指定元素,然后终止。

这里写图片描述

let disposeBag = DisposeBag()let sequenceThatFails = PublishSubject<String>()sequenceThatFails.catchErrorJustReturn("error!")                 .subscribe { print($0) }                 .addDisposableTo(disposeBag)sequenceThatFails.onNext("A")sequenceThatFails.onNext("B")sequenceThatFails.onNext("C")sequenceThatFails.onNext("D")sequenceThatFails.onError(TestError.test)输出:next(A)next(B)next(C)next(D)next(error!)completed
  • catchError

    捕获error,并转换成指定的Observable序列对error进行处理。

这里写图片描述

let disposeBag = DisposeBag()let sequenceThatFails = PublishSubject<String>()let recoverySequence = PublishSubject<String>()sequenceThatFails.catchError {            print("Error:", $0)            return recoverySequence        }.subscribe { print($0) }         .addDisposableTo(disposeBag)sequenceThatFails.onNext("1")sequenceThatFails.onNext("2")sequenceThatFails.onNext("3")sequenceThatFails.onNext("4")sequenceThatFails.onError(TestError.test)recoverySequence.onNext("5")输出:next(1)next(2)next(3)next(4)Error: testnext(5)
  • retry

    对Error事件进行重试。

这里写图片描述

let disposeBag = DisposeBag()    var count = 1let sequenceThatErrors = Observable<String>.create { observer in    observer.onNext("A")    observer.onNext("B")    observer.onNext("C")    if count == 1 {        observer.onError(TestError.test)        print("Error encountered")        count += 1    }    observer.onNext("D")    observer.onNext("E")    observer.onNext("F")    observer.onCompleted()    return Disposables.create()}sequenceThatErrors.retry()                  .subscribe(onNext: { print($0) })                  .addDisposableTo(disposeBag)输出:ABCError encounteredABCDEF
  • retry(_:)

指定最大的重试次数。

let disposeBag = DisposeBag()var count = 1let sequenceThatErrors = Observable<String>.create { observer in    observer.onNext("A")    observer.onNext("B")    observer.onNext("C")    if count < 5 {        observer.onError(TestError.test)        print("Error encountered")        count += 1    }    observer.onNext("D")    observer.onNext("E")    observer.onNext("F")    observer.onCompleted()    return Disposables.create()}sequenceThatErrors.retry(3)                  .subscribe(onNext: { print($0) })                  .addDisposableTo(disposeBag)输出:ABCError encounteredABCError encounteredABCError encounteredReceived unhandled error: /Demo/RxSwift-master/RxExample/RxExample/iOS/AppDelegate.swift:705:application(_:didFinishLaunchingWithOptions:) -> test

调试操作符

调试Rx代码的操作符

  • debug

打印所有的subscriptions,events,和disposals。

let disposeBag = DisposeBag()var count = 1let sequenceThatErrors = Observable<String>.create { observer in    observer.onNext("A")    observer.onNext("B")    observer.onNext("C")    if count < 5 {        observer.onError(TestError.test)        print("Error encountered")        count += 1    }    observer.onNext("D")    observer.onNext("E")    observer.onNext("F")    observer.onCompleted()    return Disposables.create()    }sequenceThatErrors.retry(3)                  .debug()                  .subscribe(onNext: { print($0) })                  .addDisposableTo(disposeBag)输出:2017-01-24 15:25:40.991: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> subscribed2017-01-24 15:25:41.013: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(A)A2017-01-24 15:25:41.013: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(B)B2017-01-24 15:25:41.013: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(C)CError encountered2017-01-24 15:25:41.014: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(A)A2017-01-24 15:25:41.014: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(B)B2017-01-24 15:25:41.014: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(C)CError encountered2017-01-24 15:25:41.015: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(A)A2017-01-24 15:25:41.015: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(B)B2017-01-24 15:25:41.015: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(C)CError encountered2017-01-24 15:25:41.016: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event error(test)Received unhandled error: /Demo/RxSwift-master/RxExample/RxExample/iOS/AppDelegate.swift:732:application(_:didFinishLaunchingWithOptions:) -> test2017-01-24 15:25:41.016: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> isDisposed
  • RxSwift.Resources.total

查看RxSwift所有资源的占用,对于检查内存泄露是很有用的。

print(RxSwift.Resources.total)let disposeBag = DisposeBag()print(RxSwift.Resources.total)let variable = Variable("A")let subscription1 = variable.asObservable().subscribe(onNext: { print($0) })print(RxSwift.Resources.total)let subscription2 = variable.asObservable().subscribe(onNext: { print($0) })print(RxSwift.Resources.total)subscription1.dispose()print(RxSwift.Resources.total)subscription2.dispose()print(RxSwift.Resources.total)输出:01A4A654
1 0
原创粉丝点击