RxSwift干货RXswiftRxSwift

RxSwift文档翻译3 --Combination Opera

2017-06-01  本文已影响100人  小白猿

前言

本章节的介绍操作主要是是将多个观察序列合成一个观察序列

Combination Operators

example("startWith") {
    let disposeBag = DisposeBag()

    Observable.of("🐶", "🐱", "🐭", "🐹")
        .startWith("1️⃣")
        .startWith("2️⃣")
        .startWith("3️⃣", "🅰️", "🅱️")
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}

// 控制台打印的结果:
--- startWith example ---
3️⃣
🅰️
🅱️
2️⃣
1️⃣
🐶
🐱
🐭
🐹
example("merge") {
    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("③")
}

// 控制台打印的结果:
--- merge example ---
🅰️
🅱️
①
②
🆎
③
example("zip") {
    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)
}
// 控制台打印的结果:
--- zip example ---
🅰️ 1
🅱️ 2
🆎 3

// 本文不作者修改的程序1
         example("zip") {
            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)
            // 这里添加一个事件元素
            intSubject.onNext(4)
        }

// 控制台打印的结果:
--- zip example ---
🅰️ 1
🅱️ 2
🆎 3
  
// 本文不作者修改的程序2
example("zip") {
            let disposeBag = DisposeBag()
            
            let stringSubject = PublishSubject<String>()
            let intSubject = PublishSubject<Int>()
            let intSubject2 = PublishSubject<Int>()
            
            Observable.zip(stringSubject, intSubject, intSubject2) { stringElement, intElement, intSubject2 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)
            
            intSubject.onNext(4)
        }  
// 控制台打印的结果:
--- zip example ---

修改程序解释:
在官方的演示程序后面我添加了两个修改的程序
1.intSubject.onNext(4),添加这一句,但是控制台没有打印,因为stringSubject没有事件元素与其配对,故没有打印
2.多添加一个观察序列intSubject2,但是由于intSubject2并没有添加任何事件元素,这意味着三个观察序列每次所以都不能成功配对,故控制台打印为空

官方演示图
example("combineLatest") {
            let disposeBag = DisposeBag()
            
            let stringSubject = PublishSubject<String>()
            let intSubject = PublishSubject<Int>()
            
            Observable.combineLatest(stringSubject, intSubject) { stringElement, intElement in
                " \(intElement)\(stringElement)"
                }
                .subscribe(onNext: { print($0) })
                .disposed(by: disposeBag)
            intSubject.onNext(1) 

            stringSubject.onNext("A")
            stringSubject.onNext("B")

            intSubject.onNext(2)
            stringSubject.onNext("C")
            stringSubject.onNext("D")
            
            intSubject.onNext(3)
            intSubject.onNext(4)
            intSubject.onNext(5)
        }

// 控制台打印的结果:
--- combineLatest example ---
 1A
 1B
 2B
 2C
 2D
 3D
 4D
 5D

combineLatest同样适用Array(或者其他的观察者序列的集合)的操作,但是要求序列集合类型必须一致,即Observer<T>的T是一种类型,否则编译前就会报错

类型不一致报错
example("Array.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)
}

// 控制台打印的结果:
--- Array.combineLatest example ---
❤️ 🍎 🐶
❤️ 🍐 🐶
❤️ 🍐 🐱
❤️ 🍊 🐱
❤️ 🍊 🐭
❤️ 🍊 🐹

本文作者注:官方的解释较为模糊,个人理解为switch是一个切换功能,用在序列元素也是一个观察序列的场景,假设将序列的序列定义oss,将序列定义为os,在oss的元素值设置为os1的时候,则响应os1的事件元素,当oss的元素值设置为os2的时候,此时响应os2的事件元素,此时os1即便有事件元素发出也不响应,当oss的元素值再切换到os1的时候,则再去相应os1的事件元素

/*:
 > Because the `combineLatest` variant that takes a collection passes an array of values to the selector function, it requires that all source `Observable` sequences are of the same type.
 ----
 ## `switchLatest`
 Transforms the elements emitted by an `Observable` sequence into `Observable` sequences, and emits elements from the most recent inner `Observable` sequence. [More info](http://reactivex.io/documentation/operators/switch.html)
 ![](http:https://img.haomeiwen.com/i954728/c0141794880b5a6f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
 */
example("switchLatest") {
    let disposeBag = DisposeBag()
    
    let subject1 = BehaviorSubject(value: "⚽️")
    let subject2 = BehaviorSubject(value: "🍎")
    
    let variable = Variable(subject1)
        
    variable.asObservable()
        .switchLatest()
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
    
    subject1.onNext("🏈")
    subject1.onNext("🏀")
    
    variable.value = subject2
    
    subject1.onNext("⚾️")
    
    subject2.onNext("🍐")
}

// 控制台打印的结果:
--- switchLatest example ---
⚽️
🏈
🏀
🍎
🍐

此官方实例中⚾️没有打印出来,因为variable(即oss)将值切换为subject2(即os2)之后,subject1(即os1)的值⚾️对subject2没有作用,故Variable不相应⚾️,为了让大家更易于理解switchLatest,我在官方的代码最后加一句variable.value = subject1,即将variable的值切换回subject1,则subjec1的事件元素⚾️将会被相应:

example("switchLatest") {
            let disposeBag = DisposeBag()
            
            let subject1 = BehaviorSubject(value: "⚽️")
            let subject2 = BehaviorSubject(value: "🍎")
            
            let variable = Variable(subject1)
            
            variable.asObservable()
                .switchLatest()
                .subscribe(onNext: { print($0) })
                .disposed(by: disposeBag)
            
            subject1.onNext("🏈")
            subject1.onNext("🏀")
            
            variable.value = subject2
            
            subject1.onNext("⚾️")
            
            subject2.onNext("🍐")
            
            variable.value = subject1
        }
// 控制台打印的结果:
--- switchLatest example ---
⚽️
🏈
🏀
🍎
🍐
⚾️

下一篇: RxSwift文档翻译4 -- Transforming Operators

上一篇下一篇

猜你喜欢

热点阅读