【RxJava】- 过滤操作符源码分析

目录

【RxJava】- 创建操作符源码分析
【RxJava】- 变换操作符源码分析
【RxJava】- 结合操作符源码分析
【RxJava】- 连接操作符源码分析

Debounce

仅在过了一段指定的时间还没发射数据时才发射一个数据。由类

ObservableDebounce
ObservableDebounceTimed

实现。

ObservableDebounce

被观察者发射数据,调用DebounceObserver的onNext方法。首先获取上一次发射数据时保存的DebounceInnerObserver(一个跳转中转类)实例,如果不为null,者先取消上一次的发射任务,再进行下一数据的发射。

调用debounce传入的数据包装实例,然后拿到包装后的数据进行发射。

所以如果数据发射过快,那么部分数据可能就会丢失。

ObservableDebounceTimed

发射数据是,创建一个延时发射器,当延时时间到达时,调用延时发射器run方法。将发射任务交给被包装的观察者对象SerializedObserver实例。调用SerializedObserver实例的onNext方法发射数据。

  • SerializedObserver
    如果上一个延迟时间没有到,新的数据发射到达时,将取消上一次的延迟计划,开始新的延时计划。

    如果上一个发射还没有完成,处于发射中,那么新的数据被存放在一个数组中,等下一次满足发射条件,然后循环发射所以数据。

Distinct

过滤掉重复的数据项。由

ObservableDistinct
ObservableDistinctUntilChanged
ObservableDistinct
key = Objects.requireNonNull(keySelector.apply(value), "The keySelector returned a null key");
b = collection.add(key);

得到数据,添加到集合(默认是HashSet),如果添加成功这发射数据,否则不发生,这样就可以过滤掉重复的数据项。

ObservableDistinctUntilChanged

ObservableDistinctUntilChanged实现很简单,在发射数据时,先检测是否已经发射过数据,如果已经发射过,就和上一个值进行比较,如果不相同就发射新的数据。

ElementAt

只发射第N项数据。由

ObservableElementAtMaybe
ObservableElementAtSingle

实现。

ObservableElementAtMaybe

实现很简单,自己查看,发射第N项数据。

ObservableElementAtSingle

功能和ObservableElementAtMaybe差不多。

Filter

按照一定规则过滤。由

ObservableFilter

实现

代码实现很简单,调用传入的过滤实例的test方法,如果返回true者发射数据,否则不发射。

First

只发射第一项(或者满足某个条件的第一项)数据,由

ObservableElementAtSingle

实现。
这个上面已经分析过了。

IgnoreElements

不发射任何数据,只发射Observable的终止通知,由

ObservableIgnoreElementsCompletable

实现。自己看源码,onNext中没有任何实现。

Last

只发射最后一项(或者满足某个条件的最后一项)数据。由

ObservableLastMaybe
ObservableLastSingle

实现。在调用onComplete时,发射最后一项数据。

Sample

定期发射Observable最近发射的数据项,由

ObservableSampleTimed
ObservableSampleWithObservable
ObservableSampleTimed

开始一个延时任务,当延时时间到达时,执行数据发射,具体自己看源码,很简单。

ObservableSampleWithObservable

不同的逻辑在SerializedObserver中,这个已经在上面讲解过了。

Skip

抑制Observable发射的前N项数据,由

ObservableSkip
ObservableSkipUntil
ObservableSkipWhile

实现。

ObservableSkip
 if (remaining != 0L) {
       remaining--;
} else {
      downstream.onNext(t);
}

很简单,自己查看源码。

ObservableSkipUntil
@Override
public void subscribeActual(Observer child) {
   ...
   other.subscribe(new SkipUntil(frc, sus, serial));
   source.subscribe(sus);
}

直到SkipUntil发射数据,才发射后面的数据,具体自己查看源码。

ObservableSkipWhile
public void onNext(T t) {
    if (notSkipping) {
         downstream.onNext(t);
     } else {
         boolean b;
         ...
            b = predicate.test(t);
         ...
         if (!b) {
             notSkipping = true;
             downstream.onNext(t);
          }
     }
 }

跳过满足条件的数据项。

SkipLast

抑制Observable发射的后N项数据,由

ObservableSkipLast
ObservableSkipLastTimed

实现。

ObservableSkipLastTimed
 if (!empty && ts > now - time) {
     empty = true;
}

if (empty) {
     break;
}

发射数据是存在数组中的当时的时间,time我们传入的间隔时间,只要在now - time发射的数据都会被抛弃。

Take

只发射前面的N项数据,使用Take操作符让你可以修改Observable的行为,只返回前面的N项数据,然后发射完成通知,忽略剩余的数据。具体可以结合上面的内容,里面很多和上面的类似,这里就不一一看源码了。

TakeLast

发射Observable发射的最后N项数据,使用TakeLast操作符修改原始Observable,你可以只发射Observable’发射的后N项数据,忽略前面的数据。

总结

其实过滤操作符大多实现都很简单,自己画几分钟就能看懂。

你可能感兴趣的:(【RxJava】- 过滤操作符源码分析)