Swift - RxSwift的使用详解8(变换操作符:buff
2018-03-16 本文已影响2764人
八级大狂风AM
八、变换操作(Transforming Observables)
变换操作指的是对原始的 Observable 序列进行一些转换,类似于 Swift 中 CollectionType 的各种转换。
1,buffer
(1)基本介绍
-
buffer方法作用是缓冲组合,第一个参数是缓冲时间,第二个参数是缓冲个数,第三个参数是线程。 - 该方法简单来说就是缓存
Observable中发出的新元素,当元素达到某个数量,或者经过了特定的时间,它就会将这个元素集合发送出来。
(2)使用样例
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
let disposeBag = DisposeBag()
override func viewDidLoad() {
let subject = PublishSubject<String>()
//每缓存3个元素则组合起来一起发出。
//如果1秒钟内不够3个也会发出(有几个发几个,一个都没有发空数组 [])
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("1")
subject.onNext("2")
subject.onNext("3")
}
}
运行结果如下:
2,window
(1)基本介绍
-
window操作符和buffer十分相似。不过buffer是周期性的将缓存的元素集合发送出来,而window周期性的将元素集合以Observable的形态发送出来。 - 同时
buffer要等到元素搜集完毕后,才会发出元素序列。而window可以实时发出元素序列。
(2)使用样例
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
let disposeBag = DisposeBag()
override func viewDidLoad() {
let subject = PublishSubject<String>()
//每3个元素作为一个子Observable发出。
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: self!.disposeBag)
})
.disposed(by: disposeBag)
subject.onNext("a")
subject.onNext("b")
subject.onNext("c")
subject.onNext("1")
subject.onNext("2")
subject.onNext("3")
}
}
运行结果如下:
3,map
(1)基本介绍
- 该操作符通过传入一个函数闭包把原来的
Observable序列转变为一个新的Observable序列。
(2)使用样例
let disposeBag = DisposeBag()
Observable.of(1, 2, 3)
.map { $0 * 10}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
运行结果如下:
4,flatMap
(1)基本介绍
-
map在做转换的时候容易出现“升维”的情况。即转变之后,从一个序列变成了一个序列的序列。 - 而
flatMap操作符会对源Observable的每一个元素应用一个转换方法,将他们转换成Observables。 然后将这些Observables的元素合并之后再发送出来。即又将其 "拍扁"(降维)成一个Observable序列。 - 这个操作符是非常有用的。比如当
Observable的元素本生拥有其他的Observable时,我们可以将所有子Observables的元素发送出来。
(2)使用样例
let disposeBag = DisposeBag()
let subject1 = BehaviorSubject(value: "A")
let subject2 = BehaviorSubject(value: "1")
let variable = Variable(subject1)
variable.asObservable()
.flatMap { $0 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
subject1.onNext("B")
variable.value = subject2
subject2.onNext("2")
subject1.onNext("C")
运行结果如下:
5,flatMapLatest
(1)基本介绍
-
flatMapLatest与flatMap的唯一区别是:flatMapLatest只会接收最新的value事件。
(2)这里我们将上例中的 flatMap 改为 flatMapLatest。
let disposeBag = DisposeBag()
let subject1 = BehaviorSubject(value: "A")
let subject2 = BehaviorSubject(value: "1")
let variable = Variable(subject1)
variable.asObservable()
.flatMapLatest { $0 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
subject1.onNext("B")
variable.value = subject2
subject2.onNext("2")
subject1.onNext("C")
运行结果如下:
6,concatMap
(1)基本介绍
-
concatMap与flatMap的唯一区别是:当前一个Observable元素发送完毕后,后一个Observable才可以开始发出元素。或者说等待前一个Observable产生完成事件后,才对后一个Observable进行订阅。
(2)这里我们将“样例3”中的 flatMap 改为 concatMap。
let disposeBag = DisposeBag()
let subject1 = BehaviorSubject(value: "A")
let subject2 = BehaviorSubject(value: "1")
let variable = Variable(subject1)
variable.asObservable()
.concatMap { $0 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
subject1.onNext("B")
variable.value = subject2
subject2.onNext("2")
subject1.onNext("C")
subject1.onCompleted() //只有前一个序列结束后,才能接收下一个序列
运行结果如下:
7,scan
(1)基本介绍
-
scan就是先给一个初始化的数,然后不断的拿前一个结果和最新的值进行处理操作。
(2)使用样例
let disposeBag = DisposeBag()
Observable.of(1, 2, 3, 4, 5)
.scan(0) { acum, elem in
acum + elem
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
运行结果如下:
8,groupBy
(1)基本介绍
-
groupBy操作符将源Observable分解为多个子Observable,然后将这些子Observable发送出来。 - 也就是说该操作符会将元素通过某个键进行分组,然后将分组后的元素序列以
Observable的形态发送出来。
(2)使用样例
let disposeBag = DisposeBag()
//将奇数偶数分成两组
Observable<Int>.of(0, 1, 2, 3, 4, 5)
.groupBy(keySelector: { (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)
运行结果如下: