RxJava操作符-merge

938 阅读3分钟

Merge通过合并多个Observable为1个,但是不保证它们间的发射顺序。如果期望保持Observable的发射顺序,请用concat操作符。

以如下demo为例

final String[] listFirst = {"A1", "A2", "A3", "A4"};
final String[] listSecond = {"B1", "B2", "B3"};

final Observable<String> odds = Observable.fromArray(listFirst);
final Observable<String> even = Observable.fromArray(listSecond);

        Observable
                .merge(odds,even)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "accept: " + integer);
                    }
                });

merge操作符

 public static <T> Observable<T> merge(ObservableSource<? extends T> source1, ObservableSource<? extends T> source2) {
 //省略
        return fromArray(source1, source2).flatMap((Function)Functions.identity(), false, 2);
    }
    
public static <T> Observable<T> fromArray(T... items) {
 //省略
 **** 将两个Observable(ObservableFromArray),生成一个新的ObservableFromArray
        return RxJavaPlugins.onAssembly(new ObservableFromArray<T>(items));
    }
    
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper, boolean delayErrors, int maxConcurrency) {
        return flatMap(mapper, delayErrors, maxConcurrency, bufferSize());
    }
    
    
@CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper,
            boolean delayErrors, int maxConcurrency, int bufferSize) {
 //省略
  **** 将上述生成的ObservableFromArray,包装成ObservableFlatMap
        return RxJavaPlugins.onAssembly(new ObservableFlatMap<T, R>(this, mapper, delayErrors, maxConcurrency, bufferSize));
    }

ObservableFlatMap.java 

public ObservableFlatMap(ObservableSource<T> source,
            Function<? super T, ? extends ObservableSource<? extends U>> mapper,
            boolean delayErrors, int maxConcurrency, int bufferSize) {
        super(source);
        this.mapper = mapper;
        this.delayErrors = delayErrors;
        this.maxConcurrency = maxConcurrency;
        this.bufferSize = bufferSize;
    }

到此,Observable是ObservableFlatMap,它的结构如下

图1

解析subscribe方法

****Consumer变为onNext
public final Disposable subscribe(Consumer<? super T> onNext) {
        return subscribe(onNext, Functions.ON_ERROR_MISSING, Functions.EMPTY_ACTION, Functions.emptyConsumer());
    }

public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
            Action onComplete, Consumer<? super Disposable> onSubscribe) {
 //省略    
        LambdaObserver<T> ls = new LambdaObserver<T>(onNext, onError, onComplete, onSubscribe);
        subscribe(ls)
        return ls;
    }
  1. 将Consumer包装成LambdaObserver
  2. 调用subscribe,也就是ObservableFlatMap ObservableFlatMap的subscribeActual方法
 @Override
    public void subscribeActual(Observer<? super U> t) {
        source.subscribe(new MergeObserver<T, U>(t, mapper, delayErrors, maxConcurrency, bufferSize));
    }
  1. 1中生成的LambdaObserver包装成MergeObserver,然后调用ObservableFromArray的方法
  2. ObservableFromArray的subscribeActual方法
 @Override
    public void subscribeActual(Observer<? super T> observer) {
        FromArrayDisposable<T> d = new FromArrayDisposable<T>(observer, array);

        observer.onSubscribe(d);

        if (d.fusionMode) {
            return;
        }

        d.run();
    }

4-1 将MergeObserver包装成FromArrayDisposable,array为demo中odds和evens 4-2 调用MergeObserver的onSubscribe方法

 @Override
        public void onSubscribe(Disposable d) {
            if (DisposableHelper.validate(this.upstream, d)) {
            **** upstream 是传入的FromArrayDisposable
                this.upstream = d;
                downstream.onSubscribe(this);
            }
        }

4-3 调用FromArrayDisposable的run方法

 void run() {
            T[] a = array;
            int n = a.length;

            for (int i = 0; i < n && !isDisposed(); i++) {
                T value = a[i];
                if (value == null) {
                    downstream.onError(new NullPointerException("The " + i + "th element is null"));
                    return;
                }
                ****downstream 是MergeObserver
                downstream.onNext(value);
            }
            if (!isDisposed()) {
                downstream.onComplete();
            }
        }

所以这里遍历odds 和even,然后分别调用downstream,也就是MergeObserver的onNext方法 4-3-1 MergeObserver的onNext方法

 @Override
        public void onNext(T t) {
        //省略
        ****p =mapper.apply(t),因为转换未写,所以还是一个ObservableFromArray
            subscribeInner(p);
        }

void subscribeInner(ObservableSource<? extends U> p) {
            for (;;) {
        ****将MergeObserver 和uniqueId 包装成InnerObserver
                    InnerObserver<T, U> inner = new InnerObserver<T, U>(this, uniqueId++);
        ****将inner添加到observers中,后面会用到
                    if (addInner(inner)) {
        **** 调用ObservableFromArray的subscribe方法
                        p.subscribe(inner);
                    }
                    break;
                
            }
        }

4-3-2 ObservableFromArray的subscribe,和上述一样,只是此时的observer是InnerObserver

@Override
    public void subscribeActual(Observer<? super T> observer) {
        FromArrayDisposable<T> d = new FromArrayDisposable<T>(observer, array);

        observer.onSubscribe(d);

        if (d.fusionMode) {
            return;
        }

        d.run();
    }

查看InnerObserver的onSubscribe方法

public void onSubscribe(Disposable d) {
            if (DisposableHelper.setOnce(this, d)) {
                if (d instanceof QueueDisposable) {
                    @SuppressWarnings("unchecked")
                    QueueDisposable<U> qd = (QueueDisposable<U>) d;

                    int m = qd.requestFusion(QueueDisposable.ANY | QueueDisposable.BOUNDARY);
                    if (m == QueueDisposable.SYNC) {
                        fusionMode = m;
                    **** 将q存入到queue中
                        queue = qd;
                        done = true;
                    **** parent 上述创建的时候传入了,是MergeObserver
                        parent.drain();
                        return;
                    }
                  
                }
            }
        }

4-3-3 MergeObserver的drain方法,这个方法很长,截取重要部分

void drain() {
            if (getAndIncrement() == 0) {
                drainLoop();
            }
        }

void drainLoop() {
**** downstream 是LambdaObserver
            final Observer<? super U> child = this.downstream;
            int missed = 1;
            for (;;) {
                if (checkTerminate()) {
                    return;
                }
               //省略 
                boolean d = done;
                svq = queue;
                **** 获取加入的inner
                InnerObserver<?, ?>[] inner = observers.get();
                int n = inner.length;

     
                boolean innerCompleted = false;
          //省略 
                    for (int i = 0; i < n; i++) {
                        if (checkTerminate()) {
                            return;
                        }

                        @SuppressWarnings("unchecked")
                        InnerObserver<T, U> is = (InnerObserver<T, U>)inner[j];
                        SimpleQueue<U> q = is.queue;
            **** 这个q就是ObservableFromArrayDisposable
                        if (q != null) {
            **** 循环遍历元素            
                            for (;;) {
                                U o;
                            
                                    o = q.poll();
            **** 元素遍历完退出循环
                                 if (o == null) {
                                    break;
                                }
            **** 通过child 也就是LambdaObserver,继续分发
                                child.onNext(o);

                              
                            }
                        }
      //省略 
                     
            }
        }

第二个even 也是一样,重复执行4-3-1后面的流程,但是因为两着差不多是并行的,所以发射的数据的顺序不保证。