RxSwift - 过滤操作符系列之 2

本文最后更新于 2021年4月4日 晚上

文内介绍的是过滤操作符的一些实际使用场景.

额外介绍一些过滤操作符以及一些实际开发的做法, 包括如下:

  1. share 操作符

  2. filter 操作符

  3. 将老的异步代码转换为返回可观察序列

  4. takeLast 操作符

  5. take(_: scheduler:) 即只在固定时间段内取元素, 否则自动取消订阅.

  6. throttle 操作符: 在固定时间段内只取第一个元素.

代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
1. share 操作符
如果不作处理的话, 每次针对某个 Observable 的订阅均会引起 Observable 调用 create. 且可能每次 create 时序列中的
元素都和之前的不一样了.
故可以使用 share 操作符来避免这种多余的 create 发生.
share 操作符的原理是: 只有当订阅者的数量从 0 到 1 时才会调用 create. 如果之后的订阅者进来, share 则会提供之前已经创建
好的订阅供它们使用.
当所有的订阅都被释放后, share 也会将共享序列释放掉.
这个操作符暂时没有例子.
*/

/*
2. filter 操作符: 过滤效果和 swift 本身提供的类似.
另外可以利用 filter 操作符来做一些额外的工作, 比如在判断的同时进行一些计算, 并将结果保存到对象的属性中.
*/
private func filterElem() {
exampleOf(msg: "过滤操作符: filter", action: { bag in
let obv = Observable.of(1, 3, 5, 7, 9, 2, 4, 6, 8, 10)
obv.filter({ $0 % 2 == 0 }).subscribe(onNext: {
print($0)
}, onError: {
print($0)
}, onCompleted: {
print("完成")
}, onDisposed: {
print("被释放")
}).disposed(by: bag)
})
}

/*
3. 将老的异步代码转换为返回 Observable 或 Traits 或 Subject 的办法很简单:
*/
private func createAnObservable() {
let observable = Observable<Data>.create({ observer in
let disposeables = Disposables.create()
let session = URLSession.shared
session.dataTask(
with: URL(string: "https://www.baidu.com")!,
completionHandler: { data, resp, error in
if let error = error {
observer.onError(error)
}
observer.onNext(data!)
observer.onCompleted()
}).resume()
return disposeables
})
observable.subscribe(onNext: {
print($0)
}, onError: {
print($0)
}, onCompleted: {
print("完成")
}, onDisposed: {
print("被释放")
}).disposed(by: disposeBag)
}

/*
4. takeLast 操作符: 不用再费劲心机想跳过多少多少个了, 直接取最后一个
*/
private func takeLastElem() {
exampleOf(msg: "takeLast 操作符", action: { bag in
let obv = Observable.of(1,2,3,4,5,6)
obv.takeLast(1)
.subscribe(onNext: {
print($0)
}, onError: {
print($0)
}, onCompleted: {
print(" takeLast 的那个订阅完成")
}, onDisposed: {
print("释放 takeLast 订阅")
}).disposed(by: bag)
})
}

/*
5. take(_: scheduler:) 在等待一段时机后自动结束某个订阅: 在网络操作下非常常见.
通过下面这个例子可以发现, 停止订阅时正好间隔了 5 秒(时间在 μs 即微秒级别上有误差.)
*/
private func takeSomeTime() {
let publish = PublishSubject<Void>()
print("当前时间戳: \(Date().timeIntervalSinceReferenceDate)")
publish.take(5.0, scheduler: MainScheduler.instance).subscribe(onNext: {
print("发布了!")
print("当前时间戳: \(Date().timeIntervalSinceReferenceDate)")
}, onError: {
print($0)
}, onCompleted: {
print("完成")
print("当前时间戳: \(Date().timeIntervalSinceReferenceDate)")
}, onDisposed: {
print("被释放")
print("当前时间戳: \(Date().timeIntervalSinceReferenceDate)")
}).disposed(by: disposeBag)
publish.onNext(())
}

/*
6. throttle 操作符: 过滤掉指定时间段内的相邻元素, 即固定时间段内只取一个元素.
这个操作符用来处理连续点击的情况非常有用.
暂无示例.
*/

RxSwift - 过滤操作符系列之 2
https://blog.rayy.top/2018/11/24/2019-21-rx-filter/
作者
貘鸣
发布于
2018年11月24日
许可协议