Rxjava(变换类)-Window
来源:互联网 发布:我要复仇知乎 编辑:程序博客网 时间:2024/06/07 12:39
定期将来自原始Observable的数据分解为一个Observable窗口,发射这些窗口,而不是每次 发射一项数据
创建了一个OperatorWindowWithSize,当我们subscribe的时候会调用他的call
这里skip==size,创建一个WindowExact
requested设置为了0
这里的childSubscriber换成了是WindowExact
这里由于在demo中我们再次进行了subscribe,最终会设置caughtUp为true,并且设置subscriber,这里会调用到它的onNext,最终调用到我们demo中第二个subscribe中的onNext
回到WindowExact的onNext,如果i值达到size,则置空window和index,调用window的onComplete,这样下次进来的时候会重新创建一个Window
Window和 Buffer类似,但不是发射来自原始Observable的数据包,它发射的是 Observables,这些Observables中的每一个都发射原始Observable数据的一个子集,最后发 射一个onCompleted 通知。
demo
Observable.range(1, 10).window(3).subscribe(new Action1<Observable<Integer>>() { @Override public void call(final Observable<Integer> obser) { obser.subscribe(new Action1<Integer>() { @Override public void call(Integer integer) { System.out.println(integer + " of window " + obser); } }); } });主要看下window的实现
public final Observable<Observable<T>> window(int count) { return window(count, count); }
public final Observable<Observable<T>> window(int count, int skip) { if (count <= 0) { throw new IllegalArgumentException("count > 0 required but it was " + count); } if (skip <= 0) { throw new IllegalArgumentException("skip > 0 required but it was " + skip); } return lift(new OperatorWindowWithSize<T>(count, skip)); }
创建了一个OperatorWindowWithSize,当我们subscribe的时候会调用他的call
public Subscriber<? super T> call(Subscriber<? super Observable<T>> child) { if (skip == size) { WindowExact<T> parent = new WindowExact<T>(child, size); child.add(parent.cancel); child.setProducer(parent.createProducer()); return parent; } else if (skip > size) { WindowSkip<T> parent = new WindowSkip<T>(child, size, skip); child.add(parent.cancel); child.setProducer(parent.createProducer()); return parent; } WindowOverlap<T> parent = new WindowOverlap<T>(child, size, skip); child.add(parent.cancel); child.setProducer(parent.createProducer()); return parent; }
这里skip==size,创建一个WindowExact
public WindowExact(Subscriber<? super Observable<T>> actual, int size) { this.actual = actual; this.size = size; this.wip = new AtomicInteger(1); this.cancel = Subscriptions.create(this); this.add(cancel); this.request(0); }
requested设置为了0
同样是OnSubscribeRange,最终调用到RangeProducer的fastPath
void fastPath() { final long endIndex = this.endOfRange + 1L; final Subscriber<? super Integer> childSubscriber = this.childSubscriber; for (long index = currentIndex; index != endIndex; index++) { if (childSubscriber.isUnsubscribed()) { return; } childSubscriber.onNext((int) index); } if (!childSubscriber.isUnsubscribed()) { childSubscriber.onCompleted(); } }
这里的childSubscriber换成了是WindowExact
调用它的onNext
public void onNext(T t) { int i = index; Subject<T, T> w = window; if (i == 0) { wip.getAndIncrement(); w = UnicastSubject.create(size, this); window = w; actual.onNext(w); } i++; w.onNext(t); if (i == size) { index = 0; window = null; w.onCompleted(); } else { index = i; } }index为0,创建一个UnicastSubject,size是3
actual.onNext(w);zh这里最终会调用到我们demo中的onNext,而在onNext中我们又为这个Observable做了一次订阅
然后调用 w.onNext(t);查看是否有这个窗口的订阅者,demo中我们在前面有为这个窗口添加订阅者。
public void onNext(T t) { state.onNext(t); }
public void onNext(T t) { if (!done) { if (!caughtUp) { boolean stillReplay = false; /* * We need to offer while holding the lock because * we have to atomically switch caughtUp to true * that can only happen if there isn't any concurrent * offer() happening while the emission is in replayLoop(). */ synchronized (this) { if (!caughtUp) { queue.offer(NotificationLite.next(t)); stillReplay = true; } } if (stillReplay) { replay(); return; } } Subscriber<? super T> s = subscriber.get(); try { s.onNext(t); } catch (Throwable ex) { Exceptions.throwOrReport(ex, s, t); } } }
这里由于在demo中我们再次进行了subscribe,最终会设置caughtUp为true,并且设置subscriber,这里会调用到它的onNext,最终调用到我们demo中第二个subscribe中的onNext
回到WindowExact的onNext,如果i值达到size,则置空window和index,调用window的onComplete,这样下次进来的时候会重新创建一个Window
0 0
- Rxjava(变换类)-Window
- Rxjava(变换类)--map
- Rxjava(变换类)--FlatMap
- Rxjava(变换类)--FlatMap2
- Rxjava(变换类)-concatMap
- Rxjava(变换类)-Buffer
- Rxjava(变换类)-scan
- Rxjava(变换类)-GroupBy
- RxJava变换
- RxAndroid与RxJava 变换
- RxJava-变换操作
- RxJava的变换操作
- RXJava 变换操作
- RxJava系列之二 变换类操作符详解1
- RxJava使用(四)变换
- RxJava操作符(2)-变换
- Rxjava源码(二)-----变换
- RxJava使用(四)变换
- HDOJ 5326 Work(类似并查集)
- java8中的系统时间获取
- 独木桥
- Ubuntu Server如何配置SFTP
- Leetcode123 hard
- Rxjava(变换类)-Window
- nginx入门(1)
- Android 手机开发和机顶盒开发的区别(软件角度)
- BSOJ1054 洛谷P1054 CODEVS1107【NOIP 2005提高】等价表达式 随机化
- android编译系统分析(三)make
- MyBatis学习总结(八)——Mybatis3.x与Spring4.x整合
- JAVA.SECURITY.POLICY 配置说明
- mac OSX 创建nginx + rtmp本地推流服务器
- cordova iOS 调起通讯录崩溃问题