前言
- Swift进阶之RxSwift(一)
- Swift进阶之RxSwift(二)
- Demo地址,个人水平有限,如有问题,欢迎指出!!
- 第一部分讲解了Observable的创建和使用,在第二部分讲解了Observable的一些高阶用法,本文进行Observable的进一步学习,相对于上一篇,本文要稍微简单一丢丢!
步入正题
1.Filtering and Conditional Operators 筛选和条件操作
有时候订阅者接收到的事件并不是想要的,这时候就需要用到我们下面的筛选操作了
-
filter
对接收到的事件进行筛选,返回符合条件的事件
let disposeBag = DisposeBag()
/// 筛选🐱,很容易是吧!
Observable.of(
"🐱", "🐰", "🐶",
"🐸", "🐱", "🐰",
"🐹", "🐸", "🐱")
.filter {
$0 == "🐱"
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
/// 打印结果
🐱
🐱
🐱
-
distinctUntilChanged
当接收到的事件与之前的事件相同时,不执行订阅操作。
let disposeBag = DisposeBag()
Observable.of("🐱", "🐷", "🐱", "🐱", "🐱", "🐵", "🐱")
.distinctUntilChanged()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
/// 打印结果
🐱
🐷
🐱
🐵
🐱
-
elementAt
执行指定位置的事件
let disposeBag = DisposeBag()
Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
.elementAt(3)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
/// 打印结果
🐸
- single & single with conditions
/// 不带条件的single,返回接收到的第一个事件
Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
.single()
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
/// 返回满足条件的事件,当所有事件均不满足条件是,返回error
Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
.single { $0 == "🐸" }
.subscribe { print($0) }
.disposed(by: disposeBag)
-
take
发送指定数量的事件
Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
.take(3)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
-
takeLatest
take是从前完后,这个是从后往前
Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
.takeLast(3)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
-
takeWhile
添加条件
Observable.of(1, 2, 3, 4, 5, 6)
.takeWhile { $0 < 4 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
-
takeUntil
和另一个观测序列进行关联,当另一个观测序列发送第一个事件后,订阅者接收之前的事件并结束,对以后发送的事件不进行处理!
let sourceSequence = PublishSubject<String>()
let referenceSequence = PublishSubject<String>()
sourceSequence
.takeUntil(referenceSequence)
.subscribe { print($0) }
.disposed(by: disposeBag)
sourceSequence.onNext("🐱")
sourceSequence.onNext("🐰")
sourceSequence.onNext("🐶")
referenceSequence.onNext("🔴")
sourceSequence.onNext("🐸")
sourceSequence.onNext("🐷")
sourceSequence.onNext("🐵")
/// 打印结果
next(🐱)
next(🐰)
next(🐶)
completed
-
skip
从1开始,跳过指定的事件
/// 跳过"🐱", "🐰"
Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
.skip(2)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
-
skipWhile
跳过符合条件的事件
Observable.of(1, 2, 3, 4, 5, 6)
.skipWhile { $0 < 4 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
-
skipWhileWithIndex
和上面的一样,多了个元素
Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
.skipWhileWithIndex { element, index in
index < 3
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
-
skipUntil
与takeUntil一样的道理,不多说了
let sourceSequence = PublishSubject<String>()
let referenceSequence = PublishSubject<String>()
sourceSequence
.skipUntil(referenceSequence)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
sourceSequence.onNext("🐱")
sourceSequence.onNext("🐰")
sourceSequence.onNext("🐶")
/// referenceSequence发送事件
referenceSequence.onNext("🔴")
/// referenceSequence 发送事件后结束,一下事件均不会被处理
sourceSequence.onNext("🐸")
sourceSequence.onNext("🐷")
sourceSequence.onNext("🐵")
2.Mathematical and Aggregate Operators 数据与集合操作
-
toArray
订阅者将拿到的事件转换为Array
Observable.range(start: 1, count: 10)
.toArray()
.subscribe { print($0) }
.disposed(by: disposeBag)
Observable.of("nice", "to", "meet", "you")
.toArray()
.subscribe({ (event) in
print(event.element ?? "nil")
}).disposed(by: disposeBag)
-
reduce
这个方法是对上文中的scan进一步操作,scan返回每一次操作后的事件,但reduce只返回最后一个事件
Observable.of(10, 100, 1000)
.reduce(1, accumulator: { (old, new) -> Int in
return old + new
}).subscribe({ (event) in
print(event.element ?? "nil")
}).disposed(by: disposeBag)
-
concat
对两个序列进行关联
let subject1 = BehaviorSubject(value: "🍎")
let subject2 = BehaviorSubject(value: "🐶")
let variable = Variable(subject1)
/// 执行订阅与concat操作
variable.asObservable()
.concat()
.subscribe { print($0) }
.disposed(by: disposeBag)
/// subject1发送事件
subject1.onNext("🍐")
subject1.onNext("🍊")
/// 切换到subject2
variable.value = subject2
/// 在subject1发送complete事件之前,subject2发送的事件都不会被执行
subject2.onNext("I would be ignored")
subject2.onNext("nither do i")
subject2.onNext("🐱")
/// subject1 发送completed事件
subject1.onCompleted()
/// 订阅者开始接受subject2最近发送的事件和以后的事件
subject2.onNext("🐭")
3.Connectable Operators 同步操作
先引入一个好玩的东西
- interval
/// 创建一个可以连续发送信号的Observable,参数一为时间间隔,参数二暂时用MainSchedule就可以了,不做深究
let interval = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
要理解同步操作,我们先看个非同步操作
let interval = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
/// 第一次订阅
_ = interval
.subscribe(onNext: { print("Subscription: 1, Event: \($0)") })
/// 延时5s后再次订阅
delay(5) {
_ = interval
.subscribe(onNext: { print("Subscription: 2, Event: \($0)") })
}
/// 打印结果
Subscription: 1, Event: 0
Subscription: 1, Event: 1
Subscription: 1, Event: 2
Subscription: 1, Event: 3
Subscription: 1, Event: 4
// 5s 后的事件,可以看到两个订阅者收到的事件是不一样的
Subscription: 1, Event: 5
Subscription: 2, Event: 0
Subscription: 1, Event: 6
Subscription: 2, Event: 1
Subscription: 1, Event: 7
Subscription: 2, Event: 2
...
-
publish
将非同步序列,转换为可同步序列,同步后接收到的事件是相同的
/// 创建可同步序列,需要注意的是,可同步序列必须完成connect()操作订阅者才能够执行订阅操作
let intSequence = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
.publish()
/// 订阅事件1,但是不会执行
intSequence
.subscribe(onNext: { print("Subscription 1:, Event: \($0)") })
/// 对观测序列进行connect操作,在实际情况中应该在序列初始化时进行此操作,这里为了查看测试效果,延时2s建立联系
delay(2) { _ = intSequence.connect() }
/// 4s后订阅事件2
delay(4) {
intSequence
.subscribe(onNext: { print("Subscription 2:, Event: \($0)") })
}
/// 6s后订阅事件3
delay(6) {
intSequence
.subscribe(onNext: { print("Subscription 3:, Event: \($0)") })
}
/// 打印结果
// 2s间隔,订阅1和2接收事件
Subscription 1:, Event: 0
Subscription 1:, Event: 1
Subscription 2:, Event: 1
Subscription 1:, Event: 2
Subscription 2:, Event: 2
// 6s后
Subscription 1:, Event: 3
Subscription 2:, Event: 3
Subscription 3:, Event: 3
Subscription 1:, Event: 4
Subscription 2:, Event: 4
Subscription 3:, Event: 4
-
replay
讲观测序列转换为同步序列,为每个订阅者都发送所有的事件
let intSequence = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
.replay(5)
/// 订阅1
_ = intSequence
.subscribe(onNext: { print("Subscription 1:, Event: \($0)") })
/// 延时2s进行连接
delay(2) { _ = intSequence.connect() }
/// 延时4s订阅2
delay(4) {
_ = intSequence
.subscribe(onNext: { print("Subscription 2:, Event: \($0)") })
}
/// 延时8s订阅3
delay(8) {
_ = intSequence
.subscribe(onNext: { print("Subscription 3:, Event: \($0)") })
}
///打印结果
// 2s间隔,订阅1和2同时接收事件
Subscription 1:, Event: 0
Subscription 2:, Event: 0
Subscription 1:, Event: 1
Subscription 2:, Event: 1
Subscription 1:, Event: 2
Subscription 2:, Event: 2
Subscription 1:, Event: 3
Subscription 2:, Event: 3
Subscription 1:, Event: 4
Subscription 2:, Event: 4
// 8s后订阅3接收所有事件,与订阅1,2同步
Subscription 3:, Event: 0
Subscription 3:, Event: 1
Subscription 3:, Event: 2
Subscription 3:, Event: 3
Subscription 3:, Event: 4
Subscription 1:, Event: 5
Subscription 2:, Event: 5
Subscription 3:, Event: 5
Subscription 1:, Event: 6
Subscription 2:, Event: 6
Subscription 3:, Event: 6
...
-
multicast
将可观测序列转换为同步序列,通过特定的subject来广播事件
let subject = PublishSubject<Int>()
/// 订阅subject
_ = subject
.subscribe(onNext: { print("Subject: \($0)") })
/// 序列转换
let intSequence = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
.multicast(subject)
/// 订阅1
_ = intSequence
.subscribe(onNext: { print("\tSubscription 1:, Event: \($0)") })
/// connect
delay(2) { _ = intSequence.connect() }
/// 订阅2
delay(4) {
_ = intSequence
.subscribe(onNext: { print("\tSubscription 2:, Event: \($0)") })
}
/// 订阅3
delay(6) {
_ = intSequence
.subscribe(onNext: { print("\tSubscription 3:, Event: \($0)") })
}
/// 打印结果
Subject: 0
Subscription 1:, Event: 0
Subject: 1
Subscription 1:, Event: 1
Subscription 2:, Event: 1
Subject: 2
Subscription 1:, Event: 2
Subscription 2:, Event: 2
Subject: 3
Subscription 1:, Event: 3
Subscription 2:, Event: 3
Subscription 3:, Event: 3
Subject: 4
Subscription 1:, Event: 4
Subscription 2:, Event: 4
Subscription 3:, Event: 4
...
总结
终于完了,是不是特别有成就感啊!哈哈!
RxSwift可以说是swift语言下进行MVVM最棒的工具了,如果小伙伴们之前有使用过ReactiveObjc的话,会发现RxSwift和ReactiveObjc有异曲同工之妙。好了废话不多说,祝各位在ios开发道路上一帆风顺!
另外还有一丢丢
Swift进阶之RxSwift(四)
如果觉得本文有用的话,欢迎点个喜欢,有问题也可留言!