定期将来自原始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