RxSwift官方使用示例之<组合操作符>

avatar
iOS 开发工程师 @抖音视界有限公司

本文是示例主要来自于官方的实例代码,可从这里下载 ,实例代码稍有改动。其中的图片来自于reactivex.io/

本文主要的作用是查看实例代码并查看对应实例代码的效果,不需要运行项目

操作符目录

debug 操作符会打印所有的 subscriptions, events, disposals

startWith

在发出原序列之前发送指定的元素序列

image.png

let disposeBag = DisposeBag()
    
Observable.of("🐶", "🐱", "🐭", "🐹")    // A
    .startWith("1️⃣")                    // B
    .startWith("2️⃣")                    // C
    .startWith("3️⃣", "🅰️", "🅱️")         // D
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

理解:按照说明,在发出A之前先发送B,在发送B之前先发送C,在发送C之前发送D。总的顺序就变成了DCBA 打印

3️⃣
🅰️
🅱️
2️⃣
1️⃣
🐶
🐱
🐭
🐹

merge

将原 Observable 序列中的元素组合成一个新的 Observable 序列,并在每个原 Observable 序列发出时发出每个元素

image.png

let disposeBag = DisposeBag()
            
let subject1 = PublishSubject<String>()
let subject2 = PublishSubject<String>()

Observable.of(subject1, subject2)
    .merge()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

subject1.onNext("🅰️")
subject1.onNext("🅱️")

subject2.onNext("①")
subject2.onNext("②")

subject1.onNext("🆎")
subject2.onNext("③")

打印

🅰️
🅱️
①
②
🆎
③

zip

将最多 8 个源 Observable 序列组合成一个新的 Observable 序列,并将从组合的 Observable 序列中发出来自每个源 Observable 序列的相应索引处的元素

image.png

let disposeBag = DisposeBag()
        
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("🅰️")
stringSubject.onNext("🅱️")

intSubject.onNext(1)
intSubject.onNext(2)

stringSubject.onNext("🆎")
intSubject.onNext(3)

打印

🅰️ 1
🅱️ 2
🆎 3

combineLatest

将多达 8 个源 Observable 序列组合成一个新的 Observable 序列,一旦所有源序列都发出至少一个元素,并且当任何源 Observable 序列发出一个新元素时,组合序列会发出新的组合元素

image.png

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

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

stringSubject.onNext("🅰️")
stringSubject.onNext("🅱️")
intSubject.onNext(1)
intSubject.onNext(2)
stringSubject.onNext("🆎")

打印

🅱️ 1
🅱️ 2
🆎 2

Array.combineLatest

要结合combineLatest来理解

let disposeBag = DisposeBag()
    
let stringObservable = Observable.just("❤️")
let fruitObservable = Observable.from(["🍎", "🍐", "🍊"])
let animalObservable = Observable.of("🐶", "🐱", "🐭", "🐹")

Observable.combineLatest([stringObservable, fruitObservable, animalObservable]) {
        "\($0[0]) \($0[1]) \($0[2])"
    }
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

要理解这个结果,重要的是把三个序列理解成三个分别发送元素的序列组合在一起,并且每发送一个元素都会有导致组合序列发送数据,三个序列分别发送到的第一个元素组合成一个新元素发送:❤️ 🍎 🐶 ,然后第一个序列没有再发送元素,所以第一个序列一直都是❤️ ;接下来第二个序列发送🍐,分别和第一个序列元素最近的元素❤️和第三个序列的最近元素🐶组合成新元素发送:❤️ 🍐 🐶 ;接下来第三个元素发送🐱,分别和第一个序列元素最近的元素❤️和第二个序列的最近元素🍐组合成新元素发送:❤️ 🍐 🐱 ,依次类推即可得打印结果

打印

❤️ 🍎 🐶 
❤️ 🍐 🐶 
❤️ 🍐 🐱
❤️ 🍊 🐱
❤️ 🍊 🐭
❤️ 🍊 🐹

switchLatest

Observable 序列发出的元素转换为 Observable 序列,并从最新的内部 Observable 序列发出元素 image.png

let disposeBag = DisposeBag()
    
let subject1 = BehaviorSubject(value: "⚽️")
let subject2 = BehaviorSubject(value: "🍎")

let subjectsSubject = BehaviorSubject(value: subject1)
    
subjectsSubject.asObservable()
    .switchLatest()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

subject1.onNext("🏈")
subject1.onNext("🏀")

// 更换内部序列
subjectsSubject.onNext(subject2)

subject1.onNext("⚾️")
subject2.onNext("🍐")

打印

⚽️
🏈
🏀
🍎
🍐

withLatestFrom

通过将第一个源中的每个元素与第二个源中的最新元素(如果有)组合,将两个可观察序列合并为一个可观察序列

let disposeBag = DisposeBag()
        
let foodSubject = PublishSubject<String>()
let drinksSubject = PublishSubject<String>()

foodSubject.asObservable()
    .withLatestFrom(drinksSubject) { "\($0) + \($1)" }
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

foodSubject.onNext("🥗")
drinksSubject.onNext("☕️")
foodSubject.onNext("🥐")
drinksSubject.onNext("🍷")
foodSubject.onNext("🍔")
foodSubject.onNext("🍟")
drinksSubject.onNext("🍾")

打印

🥐 + ☕️
🍔 + 🍷
🍟 + 🍷