RxSwift篇章
一:Transforming Observables
1.map
定义:transform the items emitted by an Observable by applying a function to each item
- map传入函数作用于可观察序列发出的元素.
let mapOb = Observable.of(1, 2, 3)
mapOb.map { (number) -> Int in
return number * 2
}
.subscribe {
print($0)
}
.disposed(by: disposeBag)
2.flatMap
定义:transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable
-
FlatMap操作符通过对源Observable发出的每个条目应用一个指定的函数来转换一个Observable,这个Observable可响应订阅.即:FlatMap合并了这些Observable可观察到的结果,将这些合并后的结果作为它自己的序列发出。
-
这个方法是有用的,例如: 序列中 具有可观察到的成员或以其他方式转换成可见的,这样就可以创建一个新的可观察对象,它发出由这些项目的子可观察对象发出的项目的完整集合。
struct PLPlayer {
let score: BehaviorSubject<Int>
init(score: Int) {
self.score = BehaviorSubject(value: score)
}
}
//flatMap
let boy = PLPlayer(score: 100)
let girl = PLPlayer(score: 90)
let player = BehaviorSubject(value: boy)
player.asObservable()
.flatMap { $0.score.asObservable() }
.subscribe(
onNext: { print($0) }
)
.disposed(by: disposeBag)
boy.score.onNext(60)
player.onNext(girl)
boy.score.onNext(50)
boy.score.onNext(40)
girl.score.onNext(10)
girl.score.onNext(0)
3.scan
定义: apply a function to each item emitted by an Observable, sequentially, and emit each successive value
- 从初始就带有一个默认值开始,然后对可观察序列发出的每个元素应用累加器闭包,并以单个元素可观察序列的形式返回每个中间结果.
Observable.of(10, 100, 1000)
.scan(1) { aggregateValue, newValue in
aggregateValue + newValue
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
二:Filtering Observables
1.filter
定义: emit only those items from an Observable that pass a predicate test *控制序列只发出满足条件的信号.
Observable.of (1, 2, 3, 4, 5)
.filter { $0 % 2 == 0}
.subscribe { (event) in
print(event)
}
.disposed(by: disposeBag)
2.distinctUntilChanged
定义: suppress duplicate items emitted by an Observable
- 禁止序列发出重复的信号.
Observable.of("1", "2", "2", "3")
.distinctUntilChanged()
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
3.elementAt
定义: emit only item n emitted by an Observable
- 在源可观察对象发出的项序列中提取位于指定索引位置的项,并将该项作为其自身的唯一发射发出。
Observable.of("1", "2", "3", "4")
.elementAt(2)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
4.single
- 只发出可观察序列发出的第一个元素(或满足条件的第一个元素)。如果可观察序列发出多个元素,将抛出一个错误。
Observable.of("A", "B")
.single().subscribe { (event) in
print(event)
}
.disposed(by: disposeBag)
Observable.of("A", "B", "C")
.single { $0 == "B" }
.subscribe { (event) in
print(event)
}
.disposed(by: disposeBag)
5.take
定义: emit only the first n items emitted by an Observable
- 控制一个Observable只发出前n个条目
Observable.of("A", "B", "C")
.take(2)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
6.takeLast
定义: emit only the final n items emitted by an Observable
- 控制一个Observable只发出后n个条目
Observable.of("A", "B", "C")
.takeLast(2).subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
7.takeWhile
定义: mirror items emitted by an Observable until a specified condition becomes false
- 只要指定条件的值为true,就从可观察序列的开始依次发出元素,直到条件false结束.
Observable.of (1, 2, 3, 4, 5)
.takeWhile { $0 < 3 }
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
8.takeUntil
定义: discard any items emitted by an Observable after a second Observable emits an item or terminates
- 序列发出信号,直到第二个观察对象(referenceSequence)发出一个项目或终止后,序列结束.
let sourceSequence = PublishSubject<String>()
let referenceSequence = PublishSubject<String>()
sourceSequence
.takeUntil(referenceSequence)
.subscribe { print($0) }
.disposed(by: disposeBag)
sourceSequence.onNext("A")
sourceSequence.onNext("B")
referenceSequence.onNext("C") // 条件一出来,就结束...下面不走了
sourceSequence.onNext("D")
sourceSequence.onNext("E")
9.skip
定义: suppress the first n items emitted by an Observable
- 禁止序列发出前n个项目
Observable.of(1, 2, 3, 4, 5, 6)
.skip(2)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
10.skipUntil
定义: discard items emitted by an Observable until a second Observable emits an item
- 阻止序列发出项目,直到第二个观察对象(referenceSeq)发出一个项目.
let sourceSeq = PublishSubject<String>()
let referenceSeq = PublishSubject<String>()
sourceSeq
.skipUntil(referenceSeq)
.subscribe { print($0) }
.disposed(by: disposeBag)
// 条件不出来,下面就不执行
sourceSeq.onNext("A")
sourceSeq.onNext("B")
referenceSeq.onNext("C") // 条件一出来,就结束...下面就执行
sourceSeq.onNext("D")
sourceSeq.onNext("E")
三:Combining Observables
1.startWith
定义: emit a specified sequence of items before beginning to emit the items from the source Observable
- 在开始从可观察源发出元素之前,发出指定的元素序列
Observable.of("1","2")
.startWith("A")
.startWith("a", "b")
.subscribe(onNext: {
print($0)
})
.disposed(by: disposeBag)
结果: abA12
2.merge
定义: combine multiple Observables into one by merging their emissions
- 将源可观察序列中的元素(序列)组合成一个新的可观察序列,订阅后,可响应每个序列发出信号.
let subject1 = PublishSubject<String>()
let subject2 = PublishSubject<String>()
Observable.of(subject1, subject2)
.merge()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
subject1.onNext("A")
subject2.onNext("B")
subject1.onNext("C")
结果: ABC 任何一个响应都会勾起新序列响应.
3.zip
定义: 通过指定的函数将多个可观测项的排放组合在一起,并根据该函数的结果为每个组合排放单个项
- 将源可观测序列组合成一个新的可观测序列.
- 从新测序列中处理原序列的组合信号,这个组合信号为依次取出每个源可观测序列的元素.组合信号的个数与发出最少项的源可观察对象发出的项数相同.
- 新序列传入的函数作用于这个组合信号,控制最终发出的信号结果.
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("A")
stringSubject.onNext("B") // 到这里存储了 A B 但是不会响应(除非: 另一个响应);
intSubject.onNext(1) // 勾出一个
intSubject.onNext(2) // 勾出另一个
stringSubject.onNext("C") // 存一个
intSubject.onNext(3) // 勾出一个
// 说白了: 只有两个序列同时有值的时候才会响应,否则存值.
//结果: 输出结果与zip()函数结果一致.
// A 1
// B 2
// C 3
4.combineLatest
定义:当一个项目由两个可观察对象之一发出时,通过指定的函数组合每个可观察对象发出的最新项目,并基于该函数的结果发出项目
- 将源可观察序列组合成一个新的可观察序列.
- 从新测序列中处理原序列的组合信号,这个组合信号为依次取出每个源可观测序列的最新元素,前提条件为每个源发出至少一项.
- 新序列传入的函数作用于这个组合信号,控制最终发出的信号结果.
let stringSub = PublishSubject<String>()
let intSub = PublishSubject<Int>()
Observable.combineLatest(stringSub, intSub) { strElement, intElement in
"\(strElement) \(intElement)"
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
stringSub.onNext("A") // 存一个 A
stringSub.onNext("B") // 存一个覆盖 - 和zip不一样
intSub.onNext(1) // 发现strOB也有B 响应 B 1
intSub.onNext(2) // 覆盖1 -> 2 发现strOB 有值B 响应 B 2
stringSub.onNext("XY") // 覆盖B -> Cooci 发现intOB 有值2 响应 XY 2
//打印结果:
// B 1
// B 2
// XY 2
5.switchLatest
定义: 将发出可观察的一个可观察对象转换为单个可观察对象,该可观察对象发出最近发出的那些可观察对象发出的项
let switchLatestSub1 = BehaviorSubject(value: "A")
let switchLatestSub2 = BehaviorSubject(value: "1")
let switchLatestSub = BehaviorSubject(value: switchLatestSub1)// 选择了 switchLatestSub1 就不会监听 switchLatestSub2
switchLatestSub.asObservable()
.switchLatest()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
switchLatestSub1.onNext("B")
switchLatestSub1.onNext("C")
switchLatestSub2.onNext("2")
switchLatestSub2.onNext("3") // 2-3都会不会监听,但是默认保存由 2覆盖1 3覆盖2
switchLatestSub.onNext(switchLatestSub2) // 切换到 switchLatestSub2
switchLatestSub1.onNext("D")
switchLatestSub1.onNext("XY") // 原理同上面 下面如果再次切换到 switchLatestSub1会打印出 XY
switchLatestSub.onNext(switchLatestSub1)
//打印结果:
// A
// B
// C
// 3
// XY
四:Mathematical and Aggregate Operators
1.reduce
定义: apply a function to each item emitted by an Observable, sequentially, and emit the final value
- 从一个设置的初始化值开始,然后对一个可观察序列发出的所有元素应用累加器闭包,并以单个元素可观察序列的形式返回聚合结果
Observable.of(10, 100, 1000)
.reduce(1, accumulator: +)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
2.concat
定义: emit the emissions from two or more Observables without interleaving them
- 将多个观察对象的输出连接起来,使它们的行为类似于单个观察对象,第一个观察对象发出的所有项都先于第二个观察对象发出的任何项(如果有两个以上,则以此类推)。
let subject1 = BehaviorSubject(value: "A")
let subject2 = BehaviorSubject(value: "1")
//
let subjectsSubject = BehaviorSubject(value: subject1)
subjectsSubject.asObservable()
.concat()
.subscribe { print($0) }
.disposed(by: disposeBag)
subject1.onNext("B")
subject1.onNext("C")
//切换 subject2
subjectsSubject.onNext(subject2)
subject2.onNext("打印不出来")
subject2.onNext("2")
subject1.onCompleted() // 必须要等subject1 完成了才能订阅到!
subject2.onNext("3")
五:to Convert Observables
定义: convert an Observable into another object or data structure
1.toArray
- 将源序列信号组合为新序列的一个数组信号,源序列终止,新序列发出这个数组信号.
Observable.range(start: 1, count: 10)
.toArray()
.subscribe {
print($0)
}
.disposed(by: disposeBag)