RxSwift:操作符

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)
    
    输出:
    
    3
    A
    B
    2
    1
    OC
    C
    Java
    C++
  • 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")
    
    输出:
    
    A
    B
    1
    2
    C
    C
  • 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 1
B 2
C 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 1
B 2
C 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")

输出:
1
2
3
A
B

转换操作

  • map

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

这里写图片描述

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

输出:
1
4
9
  • 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 = 85

player.value = woman

man.score.value = 95

woman.score.value = 100

输出:

80
85
90
95
100
  • 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 = 85

player.value = woman

man.score.value = 95

woman.score.value = 100

输出:

80
85
90
100
  • scan

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

这里写图片描述

let disposeBag = DisposeBag()

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

输出:

11
111
1111

过滤和条件操作符

从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)

输出:

A
A
A
  • distinctUntilChanged

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

这里写图片描述

let disposeBag = DisposeBag()

Observable.of("A", "B", "A", "A", "A", "C", "A")
          .distinctUntilChanged()
          .subscribe(onNext: { print($0) })
          .addDisposableTo(disposeBag)

输出:

A
B
A
C
A
  • 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)

输出:

A
Received 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)
completed
next(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)

输出:

A
B
C
  • takeLast

    只处理后几个信号。

这里写图片描述

let disposeBag = DisposeBag()

Observable.of("A", "B", "C", "D", "E", "F")
          .takeLast(3)
          .subscribe(onNext: { print($0) })
          .addDisposableTo(disposeBag)

输出:

D
E
F
  • takeWhile

    只处理满足条件的信号。

这里写图片描述

let disposeBag = DisposeBag()

Observable.of(1, 2, 3, 4, 5, 6)
          .takeWhile { $0 < 4 }
          .subscribe(onNext: { print($0) })
          .addDisposableTo(disposeBag)

输出:
1
2
3
  • 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)

输出:

C
D
E
F
  • skipWhile

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

这里写图片描述

let disposeBag = DisposeBag()

Observable.of(1, 2, 3, 4, , 6)
          .skipWhile { $0 < 4 }
          .subscribe(onNext: { print($0) })
          .addDisposableTo(disposeBag)

输出:

4
5
6
  • skipWhileWithIndex

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

let disposeBag = DisposeBag()

Observable.of("A", "B", "C", "D", "E", "F")
          .skipWhileWithIndex { element, index in
            index < 3
            }
          .subscribe(onNext: { print($0) })
          .addDisposableTo(disposeBag)

输出:

D
E
F
  • 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")

输出:

E
F
G

数学和集合操作符

  • 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 = subject2

subject2.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: 0
Subscription 1:, Event: 1
Subscription 1:, Event: 2
Subscription 2:, Event: 2
Subscription 1:, Event: 3
Subscription 2:, Event: 3
Subscription 1:, Event: 4
Subscription 3:, Event: 4
Subscription 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: 0
Subscription 1:, Event: 1
Subscription 2:, Event: 0
Subscription 2:, Event: 1
Subscription 1:, Event: 2
Subscription 2:, Event: 2
Subscription 1:, Event: 3
Subscription 2:, Event: 3
Subscription 1:, Event: 4
Subscription 2:, Event: 4
Subscription 1:, Event: 5
Subscription 2:, Event: 5
Subscription 3:, Event: 1
Subscription 3:, Event: 2
Subscription 3:, Event: 3
Subscription 3:, Event: 4
Subscription 3:, Event: 5
Subscription 1:, Event: 6
Subscription 3:, Event: 6
Subscription 2:, Event: 6
Subscription 1:, Event: 7
Subscription 3:, Event: 7
Subscription 2:, Event: 7
Subscription 1:, Event: 8
Subscription 3:, Event: 8
Subscription 2:, Event: 8
Subscription 1:, Event: 9
Subscription 3:, Event: 9
Subscription 2:, Event: 9
Subscription 1:, Event: 10
Subscription 3:, Event: 10
Subscription 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: 0
Subject: 1
    Subscription 1:, Event: 1
Subject: 2
    Subscription 2:, Event: 2
    Subscription 1:, Event: 2
Subject: 3
    Subscription 2:, Event: 3
    Subscription 1:, Event: 3
Subject: 4
    Subscription 2:, Event: 4
    Subscription 3:, Event: 4
    Subscription 1:, Event: 4
Subject: 5
    Subscription 2:, Event: 5
    Subscription 3:, Event: 5
    Subscription 1:, Event: 5
Subject: 6
    Subscription 2:, Event: 6
    Subscription 3:, Event: 6
    Subscription 1:, Event: 6
Subject: 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: test
next(5)
  • retry

    对Error事件进行重试。

这里写图片描述

let disposeBag = DisposeBag()
    var count = 1

let 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)

输出:
A
B
C
Error encountered
A
B
C
D
E
F
  • retry(_:)

指定最大的重试次数。

let disposeBag = DisposeBag()
var count = 1

let 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)

输出:

A
B
C
Error encountered
A
B
C
Error encountered
A
B
C
Error encountered
Received unhandled error: /Demo/RxSwift-master/RxExample/RxExample/iOS/AppDelegate.swift:705:application(_:didFinishLaunchingWithOptions:) -> test

调试操作符

调试Rx代码的操作符

  • debug

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

let disposeBag = DisposeBag()
var count = 1

let 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:)) -> subscribed
2017-01-24 15:25:41.013: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(A)
A
2017-01-24 15:25:41.013: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(B)
B
2017-01-24 15:25:41.013: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(C)
C
Error encountered
2017-01-24 15:25:41.014: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(A)
A
2017-01-24 15:25:41.014: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(B)
B
2017-01-24 15:25:41.014: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(C)
C
Error encountered
2017-01-24 15:25:41.015: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(A)
A
2017-01-24 15:25:41.015: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(B)
B
2017-01-24 15:25:41.015: AppDelegate.swift:731 (application(_:didFinishLaunchingWithOptions:)) -> Event next(C)
C
Error encountered
2017-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:) -> test
2017-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)

输出:

0
1
A
4
A
6
5
4
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值