Rxjava(变换类)-concatMap
来源:互联网 发布:ansoft maxwell软件 编辑:程序博客网 时间:2024/06/07 09:41
demo
Observable.from(aa).concatMap(new Func1<Integer, Observable<Integer>>() { @Override public Observable<Integer> call(Integer number) { return Observable.just(number * number).subscribeOn(Schedulers.from(JobExecutor.getInstance())); } }).subscribe(new Action1<Integer>() { @Override public void call(Integer integer) { System.out.print(integer + ", "); } });
看下contctMap
public final <R> Observable<R> concatMap(Func1<? super T, ? extends Observable<? extends R>> func) { if (this instanceof ScalarSynchronousObservable) { ScalarSynchronousObservable<T> scalar = (ScalarSynchronousObservable<T>) this; return scalar.scalarFlatMap(func); } return create(new OnSubscribeConcatMap<T, R>(this, func, 2, OnSubscribeConcatMap.IMMEDIATE)); }
这里 如果 是 ScalarSynchronousObservable 就跟flatMap一样,我们看下不是ScalarSynchronousObservable类型
这里会创建一个OnSubscribeConcatMap,这里会把Func1保存到mapper,另外两个参数是 2, OnSubscribeConcatMap.IMMEDIATE
然后后面subscribe的时候会调用OnSubscribeConcatMap的call函数,我们看一下它的实现
public void call(Subscriber<? super R> child) { Subscriber<? super R> s; if (delayErrorMode == IMMEDIATE) { s = new SerializedSubscriber<R>(child); } else { s = child; } final ConcatMapSubscriber<T, R> parent = new ConcatMapSubscriber<T, R>(s, mapper, prefetch, delayErrorMode); child.add(parent); child.add(parent.inner); child.setProducer(new Producer() { @Override public void request(long n) { parent.requestMore(n); } }); if (!child.isUnsubscribed()) { source.unsafeSubscribe(parent); } }这里delayErrorMode == IMMEDIATE,走if分支,创建一个SerializedSubscriber
然后以前面创建的SerializedSubscriber另加mapper, prefetch, delayErrorMode创建ConcatMapSubscriber
public ConcatMapSubscriber(Subscriber<? super R> actual, Func1<? super T, ? extends Observable<? extends R>> mapper, int prefetch, int delayErrorMode) { this.actual = actual; this.mapper = mapper; this.delayErrorMode = delayErrorMode; this.arbiter = new ProducerArbiter(); this.wip = new AtomicInteger(); this.error = new AtomicReference<Throwable>(); Queue<Object> q; if (UnsafeAccess.isUnsafeAvailable()) { q = new SpscArrayQueue<Object>(prefetch); } else { q = new SpscAtomicArrayQueue<Object>(prefetch); } this.queue = q; this.inner = new SerialSubscription(); this.request(prefetch); }这里会创建一个ProducerArbiter,调用request,这里prefetch是2
protected final void request(long n) { if (n < 0) { throw new IllegalArgumentException("number requested cannot be negative: " + n); } // if producer is set then we will request from it // otherwise we increase the requested count by n Producer producerToRequestFrom; synchronized (this) { if (producer != null) { producerToRequestFrom = producer; } else { addToRequested(n); return; } } // after releasing lock (we should not make requests holding a lock) producerToRequestFrom.request(n); }
producer为null,调用addToRequested
private void addToRequested(long n) { if (requested == NOT_SET) { requested = n; } else { final long total = requested + n; // check if overflow occurred if (total < 0) { requested = Long.MAX_VALUE; } else { requested = total; } } }
这里把requested设置为了2
回到前面的call函数
然后调用child 的setProducer,最终会调用到这里Producer的request方法
从而调用
parent.requestMore(n);这里的parent就是我们刚刚创建的ConcatMapSubscriber,我们看下它的requestMore方法
void requestMore(long n) { if (n > 0) { arbiter.request(n); } else if (n < 0) { throw new IllegalArgumentException("n >= 0 required but it was " + n); } }arbiter就是前面创建的ProducerArbiter
public void request(long n) { if (n < 0) { throw new IllegalArgumentException("n >= 0 required"); } if (n == 0) { return; } synchronized (this) { if (emitting) { missedRequested += n; return; } emitting = true; } boolean skipFinal = false; try { long r = requested; long u = r + n; if (u < 0) { u = Long.MAX_VALUE; } requested = u; Producer p = currentProducer; if (p != null) { p.request(n); } emitLoop(); skipFinal = true; } finally { if (!skipFinal) { synchronized (this) { emitting = false; } } } }
这里n为Long.MAX_VALUE
emitting设置为true,currentProducer为null,调用emitLoop
public void emitLoop() { for (;;) { long localRequested; long localProduced; Producer localProducer; synchronized (this) { localRequested = missedRequested; localProduced = missedProduced; localProducer = missedProducer; if (localRequested == 0L && localProduced == 0L && localProducer == null) { emitting = false; return; } missedRequested = 0L; missedProduced = 0L; missedProducer = null; } long r = requested; if (r != Long.MAX_VALUE) { long u = r + localRequested; if (u < 0 || u == Long.MAX_VALUE) { r = Long.MAX_VALUE; requested = r; } else { long v = u - localProduced; if (v < 0) { throw new IllegalStateException("more produced than requested"); } r = v; requested = v; } } if (localProducer != null) { if (localProducer == NULL_PRODUCER) { currentProducer = null; } else { currentProducer = localProducer; localProducer.request(r); } } else { Producer p = currentProducer; if (p != null && localRequested != 0L) { p.request(localRequested); } } } }满足
if (localRequested == 0L && localProduced == 0L && localProducer == null)把emitting设置为false返回
再次回到call函数,调用
source.unsafeSubscribe(parent);调用source的call函数,这里的source是OnSubscribeFromIterable
public void call(final Subscriber<? super T> o) { Iterator<? extends T> it; boolean b; try { it = is.iterator(); b = it.hasNext(); } catch (Throwable ex) { Exceptions.throwOrReport(ex, o); return; } if (!o.isUnsubscribed()) { if (!b) { o.onCompleted(); } else { o.setProducer(new IterableProducer<T>(o, it)); } } }先获取值,然后调用setProducer,这里new了一个IterableProducer,最终会调用它的request方法,这里的o是ConcatMapSubscriber
@Override public void request(long n) { if (get() == Long.MAX_VALUE) { // already started with fast-path return; } if (n == Long.MAX_VALUE && compareAndSet(0, Long.MAX_VALUE)) { fastPath(); } else if (n > 0 && BackpressureUtils.getAndAddRequest(this, n) == 0L) { slowPath(n); } }这里n为2,前面初始化ConcatMapSubscriber的时候设置的
所以这里走的是slowPath
void slowPath(long n) { // backpressure is requested final Subscriber<? super T> o = this.o; final Iterator<? extends T> it = this.it; long r = n; long e = 0; for (;;) { while (e != r) { if (o.isUnsubscribed()) { return; } T value; try { value = it.next(); } catch (Throwable ex) { Exceptions.throwOrReport(ex, o); return; } o.onNext(value); if (o.isUnsubscribed()) { return; } boolean b; try { b = it.hasNext(); } catch (Throwable ex) { Exceptions.throwOrReport(ex, o); return; } if (!b) { if (!o.isUnsubscribed()) { o.onCompleted(); } return; } e++; } r = get(); if (e == r) { r = BackpressureUtils.produced(this, e); if (r == 0L) { break; } e = 0L; } } }之类调用o的onNext,o是ConcatMapSubscriber
@Override public void onNext(T t) { if (!queue.offer(NotificationLite.next(t))) { unsubscribe(); onError(new MissingBackpressureException()); } else { drain(); } }queue.offer会把当前值入队列调用drain
void drain() { if (wip.getAndIncrement() != 0) { return; } final int delayErrorMode = this.delayErrorMode; for (;;) { if (actual.isUnsubscribed()) { return; } if (!active) { if (delayErrorMode == BOUNDARY) { if (error.get() != null) { Throwable ex = ExceptionsUtils.terminate(error); if (!ExceptionsUtils.isTerminated(ex)) { actual.onError(ex); } return; } } boolean mainDone = done; Object v = queue.poll(); boolean empty = v == null; if (mainDone && empty) { Throwable ex = ExceptionsUtils.terminate(error); if (ex == null) { actual.onCompleted(); } else if (!ExceptionsUtils.isTerminated(ex)) { actual.onError(ex); } return; } if (!empty) { Observable<? extends R> source; try { source = mapper.call(NotificationLite.<T>getValue(v)); } catch (Throwable mapperError) { Exceptions.throwIfFatal(mapperError); drainError(mapperError); return; } if (source == null) { drainError(new NullPointerException("The source returned by the mapper was null")); return; } if (source != Observable.empty()) { if (source instanceof ScalarSynchronousObservable) { ScalarSynchronousObservable<? extends R> scalarSource = (ScalarSynchronousObservable<? extends R>) source; active = true; arbiter.setProducer(new ConcatMapInnerScalarProducer<T, R>(scalarSource.get(), this)); } else { ConcatMapInnerSubscriber<T, R> innerSubscriber = new ConcatMapInnerSubscriber<T, R>(this); inner.set(innerSubscriber); if (!innerSubscriber.isUnsubscribed()) { active = true; source.unsafeSubscribe(innerSubscriber); } else { return; } } request(1); } else { request(1); continue; } } } if (wip.decrementAndGet() == 0) { break; } } }active开始为false,进入后会把它设置为true,这里如果active为true,则表示前一个操作未完成,直接返回(前一个操作什么时候完成后面会讲)
出队列,主要的是调用mapper的call函数
public Observable<Integer> call(Integer number) { return Observable.just(number * number).subscribeOn(Schedulers.from(JobExecutor.getInstance())); }最终会创建一个ScalarAsyncOnSubscribe它的onSubscribe是OperatorSubscribeOn
回到drain函数,source不是ScalarSynchronousObservable,走else分支
ConcatMapInnerSubscriber<T, R> innerSubscriber = new ConcatMapInnerSubscriber<T, R>(this); inner.set(innerSubscriber); if (!innerSubscriber.isUnsubscribed()) { active = true; source.unsafeSubscribe(innerSubscriber); } else { return; } } request(1);
创建一个ConcatMapInnerSubscriber并设置给inner,inner是我们初始化时创建的SerialSubscription
并走if分支,active设置为true,调用unsafeSubscribe,最终调用ScalarAsyncOnSubscribe的call函数
public void call(Subscriber<? super T> s) { s.setProducer(new ScalarAsyncProducer<T>(s, value, onSchedule)); }
这里创建了一个ScalarAsyncProducer,调用setProducer
@Override public void setProducer(Producer p) { parent.arbiter.setProducer(p); }
这里的arbiter是ProducerArbiter,
public void setProducer(Producer newProducer) { synchronized (this) { if (emitting) { missedProducer = newProducer == null ? NULL_PRODUCER : newProducer; return; } emitting = true; } boolean skipFinal = false; try { currentProducer = newProducer; if (newProducer != null) { newProducer.request(requested); } emitLoop(); skipFinal = true; } finally { if (!skipFinal) { synchronized (this) { emitting = false; } } } }
主要调用
newProducer.request(requested);newProducer为ScalarAsyncProducer
@Override public void request(long n) { if (n < 0L) { throw new IllegalArgumentException("n >= 0 required but it was " + n); } if (n != 0 && compareAndSet(false, true)) { actual.add(onSchedule.call(this)); } }我们看一下onSchedule
w.schedule(new Action0() { @Override public void call() { try { a.call(); } finally { w.unsubscribe(); } } });
------------------------------------------------------------------------------------------------------------
这里的a是ScalarSynchronousObservable,这里已经在另外一个线程执行了
我们看一下他的call
@Override public void call() { Subscriber<? super T> a = actual; if (a.isUnsubscribed()) { return; } T v = value; try { a.onNext(v); } catch (Throwable e) { Exceptions.throwOrReport(e, a, v); return; } if (a.isUnsubscribed()) { return; } a.onCompleted(); }这里的a是ConcatMapInnerSubscriber,他的onNext函数我们就不去分析了,我们看一下他的onComplete函数
public void onCompleted() { parent.innerCompleted(produced); }这里parent为ConcatMapSubscriber
void innerCompleted(long produced) { if (produced != 0L) { arbiter.produced(produced); } active = false; drain(); }
这里会把active 设置为false重新调用drain函数,如果队列中有值,则继续执行队列中的请求
----------------------------------------------------------------------------------
我们重新回到前面第一个线程在schedule启动一个线程之后,继续回到slowPath,然后处理下一个请求,把值入队列,如果当前有请求执行,则返回。这样所有的执行都是一个接着一个执行的。
所以最终的输出结果也是顺序的
4, 9, 16, 25, 36, 49, 64, 81, 100,这里在调试的时候为了 延迟一个操作执行的时间,模拟一个操作长时间执行,drain中active 为false状态,我们可以在sursurib中添加sleep
ArrayList aa = new ArrayList<>(Arrays.asList(2, 3, 4, 5, 6, 7, 8, 9, 10)); Observable.from(aa).concatMap(new Func1<Integer, Observable<Integer>>() { @Override public Observable<Integer> call(Integer number) { return Observable.just(number * number).subscribeOn(Schedulers.from(JobExecutor.getInstance())); } }).subscribe(new Action1<Integer>() { @Override public void call(Integer integer) { System.out.print(integer + ", "); try { Thread.sleep(60000); } catch (InterruptedException e) { e.printStackTrace(); } } });
- Rxjava(变换类)-concatMap
- RxJava变换操作符:.concatMap( )与.flatMap( )的比较
- RxJava变换操作符:.concatMap( )与.flatMap( )的比较
- RxJava concatMap操作符
- RxJava concatMap操作符
- RxJava变换操作符:.concatMap( )与.flatMap( )的比较(即有序对无序)
- Rxjava(变换类)--map
- Rxjava(变换类)--FlatMap
- Rxjava(变换类)--FlatMap2
- Rxjava(变换类)-Buffer
- Rxjava(变换类)-scan
- Rxjava(变换类)-GroupBy
- Rxjava(变换类)-Window
- Android函数响应式编程——必学的RxJava变换操作符map、flatMap、cast、concatMap、flatMapIterable、buffer、groupBy
- RxJava变换
- RxJava(四) concatMap操作符用法详解
- RxAndroid与RxJava 变换
- RxJava-变换操作
- 必须记住的 30 类 CSS 选择器
- 认识React的diff算法
- 线程池详解
- #学志#html页面简单的数据传递
- 总结 XSS 与 CSRF 两种跨站攻击
- Rxjava(变换类)-concatMap
- 详解Qt中的状态机机制(一)
- 全选/全不选
- oracle如何跨库操
- 从Android原生角度看移动html5开发APP(一)原生与html对比
- Ubuntu | 安装PHP5 | PHP5.6 |
- mysql各种蛋疼的小经验
- 冒泡、二分、快速
- 动态语言