RxSwift使用技巧之过滤操作详解
副标题[/!--empirenews.page--]
前言 在前面的基础之上接下来我会介绍一些常用的函数和实用技巧。首先,本文将会介绍那些用于对 next 事件进行过滤的操作。这些过滤操作类似于 Swift 标准库中的 filter 操作。它能在我们开始真正进行业务处理前先把那些不符合条件的过滤掉,而且这种函数式编程的范式也能开阔我们的思维。 Ignore 过滤 RxSwift 中最简单直接的过滤操作就是 ignoreElements 了。该操作会屏蔽所有的 next 事件,只会将注意力放在 error 和 completed 事件上。如下图所示,在整个生命周期中可观察对象的所有 next 都被过滤。 示例代码: let strikes = PublishSubject<String>() let disposeBag = DisposeBag() strikes .ignoreElements() .subscribe { _ in print("You're out!") } .addDisposableTo(disposeBag) strikes.onNext("X") strikes.onNext("X") strikes.onNext("X") strikes.onCompleted() /* 打印结果 You're out! */ 不过相比于残暴的全部过滤,有时候我们可能只是需要过滤某些特定的事件。例如,我们可以通过 elementAt 对特定索引号 next 进行过滤。下图演示了只响应第二个 next 事件的 elementAt 操作。 与之相应的代码为: let strikes = PublishSubject<String>() let disposeBag = DisposeBag() strikes .elementAt(2) .subscribe(onNext: { str in print(str) }) .addDisposableTo(disposeBag) strikes.onNext("1") strikes.onNext("2") strikes.onNext("3") strikes.onCompleted() /* 打印结果 3 */ 上面两个操作最后针对的 next 事件最多只会有一个,但是大多数时候我们其实需要筛选出一组符合条件的 next 事件。下图演示的就是使用 filter 筛选数据小于 3 的操作。 图示对应代码如下: let strikes = PublishSubject<Int>() let disposeBag = DisposeBag() strikes .filter{ $0 < 3 } .subscribe(onNext: { num in print("(num)") }) .addDisposableTo(disposeBag) strikes.onNext(1) strikes.onNext(2) strikes.onNext(3) strikes.onNext(4) strikes.onNext(5) strikes.onCompleted() /* 打印结果 1 2 */ Skip 过滤 除了忽略操作外,另一个常见的过滤就是跳过操作了。在所有的跳过操作中,最简单的就属 skip 了。通过设定参数,我们就能和简单实现跳过指定个数的事件。例如,下图久演示跳过前两个事件的操作。 let strikes = PublishSubject<Int>() let disposeBag = DisposeBag() strikes .skip(2) .subscribe(onNext: { num in print("(num)") }) .addDisposableTo(disposeBag) strikes.onNext(1) strikes.onNext(2) strikes.onNext(3) strikes.onNext(4) strikes.onNext(5) strikes.onCompleted() /* 打印结果 3 4 5 */ 当然除了跳过指定索引号的事件之外,我们依旧通过 skipWhile 我们能够实现类似 filter 类似的操作。只不过 filter 会过滤整个生命周期内的符合条件的事件,而 skipWhile 在找到第一个不符合跳过操作的事件之后就不再工作。例如,下图 skipWhile 的条件是数据为奇数就跳过,但是当数据 2 执行之后 数据 3 虽然也是奇数但是不会在跳过。所以严格意义上来说 skipWhile 可能有点歧义,实际是它会跳过所有符合条件的事件,直到找到第一个能执行事件后就不再生效。 下面是跳过偶数的 skipWhile 代码: let strikes = PublishSubject<Int>() let disposeBag = DisposeBag() strikes .skipWhile{ num in num % 2 == 0 } .subscribe(onNext: { num in print("(num)") }) .addDisposableTo(disposeBag) strikes.onNext(2) strikes.onNext(2) strikes.onNext(3) strikes.onNext(4) strikes.onNext(5) strikes.onCompleted() /* 打印结果 3 4 5 */ 到目前为止,上面的过滤操作都是基于一些静态条件。如果现在你需要根据其它可观察对象实例的行为进行过滤判断怎么办呢?所以接下来将会介绍涉及多实例的动态判断,其中最常见的就是 skipUntil 操作。该操作过程如下图,上面两行表示可观察对象的生命周期而最下面的表示观察者,直到第二行的可观察对象发送数据后第三行的观察者才能接受到第一行发送的数据。 图示对应代码: let strikes = PublishSubject<String>() let trigger = PublishSubject<String>() let disposeBag = DisposeBag() strikes .skipUntil(trigger) .subscribe(onNext: { print($0) }) .addDisposableTo(disposeBag) strikes.onNext("1") trigger.onNext("X") strikes.onNext("2") strikes.onNext("3") strikes.onCompleted() /* 打印结果 2 3 */ Take 过滤 (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |