RxSwift(七) - 变换操作符(buffer、map、flatMap、scan等)

变换操作符

变换操作符是指对原始的 Observable 序列进行一些变换.

1. buffer

(1) 简介

  • buffer 方法的作用是缓冲组合, 第一个参数是缓冲时间, 第二个参数是缓冲个数, 第三个是参数是线程
  • buffer 的作用就是缓存 Observable 中发出的元素, 当元素达到某个数量, 或者经过指定时间, 它就会将这个元素集合发送出来.
buffer.png

(2) 案例

let disposeBag = DisposeBag()
        
let subject = PublishSubject()
//每缓存三个元素,则组合起来一起发出
//如果一秒钟内不够三个也会发出(有几个发几个, 一个没有就发送空数组)
subject.buffer(timeSpan: 1, count: 3, scheduler: MainScheduler.instance)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
        
subject.onNext("a")
subject.onNext("b")
subject.onNext("c")
        
subject.onNext("11")
subject.onNext("22")
subject.onNext("33")

//输出结果
["a", "b", "c"]
["11", "22", "33"]
2. window

(1) 简介

  • window 操作符和 buffer 十分相似. buffer 是周期性的将缓存的元素集合发送出来, 而 window 是周期性的将元素集合以 Observable 的形态发送出来
  • buffer 要等元素搜集完毕后,才会发出元素序列. 而 window 可以实时发出元素序列.
    window.png

(2) 案例

let disposeBag = DisposeBag()
        
let subject = PublishSubject()
subject.window(timeSpan: 1, count: 3, scheduler: MainScheduler.instance)
.subscribe(onNext: { [weak self] in
    print("subscribe: \($0)")
    $0.asObservable()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
})
.disposed(by: disposeBag)
        
subject.onNext("a")
subject.onNext("b")
subject.onNext("c")
         
subject.onNext("1")
subject.onNext("2")
subject.onNext("3")

//输出结果
subscribe: RxSwift.AddRef
a
b
c
subscribe: RxSwift.AddRef
1
2
3
subscribe: RxSwift.AddRef
subscribe: RxSwift.AddRef
...
3. map

(1) 简介

  • 该操作符通过传入一个函数闭包把原来的 Observable 序列转变成一个新的 Observable 序列
    map.png

(2) 案例

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

//输出结果
10
20
30
4. flatMap

(1) 简介

  • flatMap 操作符会对源 Observable 的每一个元素应用一个转换方法, 将他们转换成 Observables, 然后将这些 Observables 的元素合并之后再发出来
    flatMap.png

(2) 案例

let disposeBag = DisposeBag()
        
let first = BehaviorSubject(value: "1")
let second = BehaviorSubject(value: "A")
        
let be = Variable(first)
be.asObservable()
.flatMap { $0 }
.subscribe(onNext: { print($0) }) //订阅发送上一个event,即默认值
.disposed(by: disposeBag)
        
first.onNext("2") //发出event 2
be.value = second   //订阅second
second.onNext("B")  //发出event B
first.onNext("3")   //发出event 3

//输出结果
1
2
A
B
3
5. flatMapLatest

(1) 简介

  • flatMapLatestflatMap 的唯一区别是: flatMapLatest 只会接收最新的 value 事件
    flatMapLatest.png

(2) 案例

let disposeBag = DisposeBag()
        
let first = BehaviorSubject(value: "1")
let second = BehaviorSubject(value: "A")
        
let be = Variable(first)
be.asObservable()
.flatMapLatest { $0 }
.subscribe(onNext: { print($0) }) //订阅发送上一个event,即默认值
.disposed(by: disposeBag)
        
first.onNext("2") //发出event 2
be.value = second   //订阅second
second.onNext("B")  //发出event B
first.onNext("3")   //现在value为 second , 所以不会发出event

//输出结果
1
2
A
B
6. flatMapFirst

(1) 简介

  • flatMapFirstflatMapLatest正好相反, flatMapFirst 只会接收最初的 value 事件

(2) 案例

let disposeBag = DisposeBag()
        
let first = BehaviorSubject(value: "1")
let second = BehaviorSubject(value: "A")
        
let be = Variable(first)
be.asObservable()
.flatMapFirst { $0 }
.subscribe(onNext: { print($0) }) //订阅发送上一个event,即默认值
.disposed(by: disposeBag)
        
first.onNext("2") //发出event 2
be.value = second   //订阅second
second.onNext("B")  //只会发出最初value的event
first.onNext("3")   //发出3

//输出结果
1
2
3
7. concatMap

(1) 简介

  • concatMapflatMap的唯一区别是: 当前一个 Observable 元素发送完毕后, 后一个 Observable 才可以开始发出元素, 或者说等待前一个 Observable 产生完成事件后, 才对后一个 Observable 进行订阅
    concatMap.png

(2) 案例

let disposeBag = DisposeBag()
        
let first = BehaviorSubject(value: "1")
let second = BehaviorSubject(value: "A")
        
let be = Variable(first)
be.asObservable()
.concatMap { $0 }
.subscribe(onNext: { print($0) }) //订阅发送上一个event,即默认值
.disposed(by: disposeBag)
        
first.onNext("2") //发出event 2
be.value = second   //first未完结,只做订阅,不发出event
second.onNext("B")  //first未完结,等待处理
first.onNext("3")   //现在value为 second , 所以不会发出event
first.onCompleted(); //first完结,处理发出的event

//输出结果
1
2
3
B
8. scan

(1) 简介

  • scan 就是先给一个初始化的数, 然后不断拿前一个结果和最新的值进行处理操作
  • scan 操作符将对第一个元素应用一个函数,将结果作为第一个元素发出。然后,将结果作为参数填入到第二个元素的应用函数中,创建第二个元素。以此类推,直到遍历完全部的元素。
    (2) 案例
let disposeBag = DisposeBag()
        
Observable.of(1,2,3,4)
.scan(0) { (a, b) -> Int in
    return a + b
}.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

//输出结果
1
3
6
10
9. groupBy

(1) 简介

  • groupBy 操作符将源 Observable 分解为多个子 Observable, 然后将这些子 Observable 发送出来. 即 该操作符会根据某个条件对源 Observable 序列进行分组, 在讲分组后的元素以 Observable 的形态发送出来
    groupBy.png

(2) 案例

let disposeBag = DisposeBag()
        
Observable.of(0,1,2,3,4,5)
.groupBy { (element) -> String in
    return element % 2 == 0 ? "偶数" : "奇数"
}
.subscribe { event in
    switch event {
        case .next(let group):
        group.asObservable().subscribe { (event) in
        print("key: \(group.key)   event: \(event)" )
    }
    .disposed(by: disposeBag)
        default:
            print("")
    }
}
.disposed(by: disposeBag)

//输出结果
key: 偶数   event: next(0)
key: 奇数   event: next(1)
key: 偶数   event: next(2)
key: 奇数   event: next(3)
key: 偶数   event: next(4)
key: 奇数   event: next(5)
key: 奇数   event: completed
key: 偶数   event: completed

你可能感兴趣的:(RxSwift(七) - 变换操作符(buffer、map、flatMap、scan等))