对事件序列中的事件(序列)进行变换,使得其转变成不同的事件(序列)
| 操作符 | 描述 |
|---|---|
| amb | 传入多个 Observables 到 amb 操作符时,它将取第一个产生事件的那个 Observable |
| buffer | 周期性的将缓存的元素集合发送出来(当元素达到某个数量,或者经过了特定的时间) |
| window | 周期性的将实时的元素集合发送出来 |
| groupBy | 将元素通过某个键进行分组,然后将分组后的元素序列以 Observable 的形态发送出来 |
| scan | (累加器)将结果作为参数填入到第二个元素的应用函数中,创建第二个元素 |
| map | 将源 Observable 的每个元素应用闭包表达式的转换方法,然后返回含有转换结果的 Observable |
| flatMap | 将源 Observable 的每个元素应用闭包表达式的转换方法,转换后,即接收旧的,也接收新的 |
| flatMapFirst | 将源 Observable 的每一个元素应用一个转换方法,只接收旧的Observable |
| flatMapLatest | 将源 Observable 的每一个元素应用一个转换方法,转换后,只接收新的Observable,忽略旧的 |
| concatMap | 将源 Observable 的每一个元素应用一个转换方法,当第一个完成后,接收第二个 |
-
amb
在多个源 Observables 中, 取第一个发出元素或产生事件的 Observable,然后只发出它的元素,忽略掉其他的 Observables。
let firstObservable = Observable.just(0)
let seconedObservable = Observable.just(1)
let thirdObservable = Observable.just(2)
Observable<Int>.amb([firstObservable, seconedObservable, thirdObservable])
.subscribe(
onNext: { print($0) },
onError: { (error) in
print(error)
}, onCompleted: {
print("完成")
}).disposed(by: disposeBag)
//输出:0 完成
'那个先发出事件就接收那个。'
-
buffer
缓存元素,然后将缓存的元素集合,周期性的发出来
let subject = PublishSubject<Int>()
subject.buffer(timeSpan: DispatchTimeInterval.seconds(1), count: 3, scheduler: MainScheduler())
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
subject.onNext(1)
subject.onNext(2)
subject.onNext(3)
subject.onNext(4)
subject.onNext(5)
subject.onNext(6)
subject.onNext(7)
//输出:
[1, 2, 3]
[4, 5, 6]
间隔5S以后
[7]
间隔5S以后
[]
间隔5S以后
[]
···
'不够3个元素,间隔时间内等一下'
-
window
将 Observable 分解为多个子 Observable,周期性的将子 Observable 发出来
let subject = PublishSubject<Int>()
subject
.debug()
.window(timeSpan: DispatchTimeInterval.seconds(5), count: 3, scheduler: MainScheduler())
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
subject.onNext(1)
subject.onNext(2)
subject.onNext(3)
subject.onNext(4)
subject.onNext(5)
subject.onNext(6)
subject.onNext(7)
//输出:
RxSwift.AddRef<Swift.Int>
2019-10-23 11:54:49.050: MHigherOrderFunctionsViewController.swift:275 (testWindow()) -> subscribed
2019-10-23 11:54:49.052: MHigherOrderFunctionsViewController.swift:275 (testWindow()) -> Event next(1)
2019-10-23 11:54:49.052: MHigherOrderFunctionsViewController.swift:275 (testWindow()) -> Event next(2)
2019-10-23 11:54:49.052: MHigherOrderFunctionsViewController.swift:275 (testWindow()) -> Event next(3)
RxSwift.AddRef<Swift.Int>
2019-10-23 11:54:49.052: MHigherOrderFunctionsViewController.swift:275 (testWindow()) -> Event next(4)
2019-10-23 11:54:49.052: MHigherOrderFunctionsViewController.swift:275 (testWindow()) -> Event next(5)
2019-10-23 11:54:49.052: MHigherOrderFunctionsViewController.swift:275 (testWindow()) -> Event next(6)
RxSwift.AddRef<Swift.Int>
2019-10-23 11:54:49.052: MHigherOrderFunctionsViewController.swift:275 (testWindow()) -> Event next(7)
间隔5S以后
RxSwift.AddRef<Swift.Int>
间隔5S以后
RxSwift.AddRef<Swift.Int>
'一起发出所有元素'
window操作符和buffer十分相似,buffer周期性的将缓存的元素集合发送出来,而window周期性的将元素集合以Observable的形态发送出来。buffer要等到元素搜集完毕后,才会发出元素序列。而window可以实时发出元素序列。
-
groupBy
groupBy 操作符将源 Observable 分解为多个子 Observable,然后将这些子 Observable 发送出来。通过某个键进行分组,然后将分组后的元素序列以 Observable 的形态发送出来。
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: self.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:next(7)
key:偶数 event:completed
key:奇数 event:completed
'以键值的方式将元素分组'
-
scan
从初始就带有一个默认值开始,然后对可观察序列发出的每个元素应用累加器闭包,并以单个元素可观察序列的形式返回每个中间结果
Observable.of(10, 100, 1000)
.scan(2) { aggregateValue, newValue in
aggregateValue + newValue //10 + 2 , 100 + 10 + 2 , 1000 + 100 + 2
}
.subscribe(onNext: { print($0, terminator: " ") })
.disposed(by: disposeBag)
//输出:12 112 1112
'累加器(accumulator)每次都用到上一个元素'
-
map
转换闭包应用于可观察序列发出的元素,并返回转换后的元素的新可观察序列。
let ob = Observable.of(1, 2, 3, 4)
ob.map { (number) -> Int in
return number + 2
}
.subscribe {
print($0, terminator: " ")
}
.disposed(by: disposeBag)
输出:next(3) next(4) next(5) next(6) completed
'将源序列经过表达式变成新的序列(函数式)'
-
flatMap
将可观察序列发射的元素转换为可观察序列,并将两个可观察序列的发射合并为一个可观察序列。当 Observable 的元素本身拥有其他的 Observable 时,可以将所有子 Observables 的元素发送出来。
struct MPlayer {
init(score: Int) {
self.score = BehaviorSubject(value: score)
}
let score: BehaviorSubject<Int>
}
let boy = MPlayer(score: 100)
let girl = MPlayer(score: 90)
let player = BehaviorSubject(value: boy)
player.asObservable()
.flatMap{$0.score.asObservable()}// 本身score就是序列 模型就是序列中的序列
.subscribe(onNext: { print($0, terminator: " ") })
.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)
//输出:100 60 90 50 40 10 0
'转换后同时接收 boy 和 girl'
-
flatMapFirst
将源 Observable 的每一个元素应用一个转换方法,将他们转换成 Observables。只接收旧的 Observables 发出它的元素。 示例:
let boy = MPlayer(score: 100)
let girl = MPlayer(score: 90)
let player = BehaviorSubject(value: boy)
player.asObservable()
.flatMapFirst{$0.score.asObservable()}// 本身score就是序列 模型就是序列中的序列
.subscribe(onNext: { print($0, terminator: " ") })
.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)
//输出:100 60 50 40
'只接收boy'
-
flatMapLatest
将源 Observable 的每一个元素应用一个转换方法,将他们转换成 Observables。一旦转换出一个新的 Observable,就只发出它的元素,旧的 Observables 的元素将被忽略掉。
let boy = MPlayer(score: 100)
let girl = MPlayer(score: 90)
let player = BehaviorSubject(value: boy)
player.asObservable()
.flatMapLatest{$0.score.asObservable()}// 本身score就是序列 模型就是序列中的序列
.subscribe(onNext: { print($0, terminator: " ") })
.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)
//输出:100 60 90 10 0
'转换后只接收 girl'
flatMap转换后会接收新的和旧的发出元素,flatMapFirst只接受旧的,flatMapLatest转换后则只接收新的,忽略旧的。
-
concatMap
将源 Observable 的每一个元素应用一个转换方法,将他们转换成 Observables。然后让这些 Observables 按顺序的发出元素,当前一个 Observable 元素发送完毕后,后一个 Observable 才可以开始发出元素。 等待前一个 Observable 产生完成事件后,才对后一个 Observable 进行订阅。
let subject1 = BehaviorSubject(value: 100)
let subject2 = BehaviorSubject(value: 90)
let variable = BehaviorSubject(value: subject1)
variable.asObservable()
.concatMap { $0 }
.subscribe { print($0, terminator: " ") }
.disposed(by: disposeBag)
subject1.onNext(60)
subject1.onNext(50)
variable.onNext(subject2)
subject2.onNext(40)//被忽略
subject2.onNext(30)
subject1.onCompleted()
subject2.onNext(20)
//输出:next(100) next(60) next(50) next(30) next(20)
'subject1 完成后接收 subject2'