Rxjava的基礎用法和源碼解析(三)

這篇博客的用法主要有 : zip,amb,combineLatest ,concatEager

zip

public static <T1, T2, R> Observable<R> zip(Observable<? extends T1> o1, Observable<? extends T2> o2, final Func2<? super T1, ? super T2, ? extends R> zipFunction)
... 支持N個參數的最終合併,這裏暫時只寫出兩個的
public static <R> Observable<R> zip(Iterable<? extends Observable<?>> ws, FuncN<? extends R> zipFunction)
public static <R> Observable<R> zip(Observable<? extends Observable<?>> ws, final FuncN<? extends R> zipFunction)

首先是

 public static <T1, T2, R> Observable<R> zip(Observable<? extends T1> o1, Observable<? extends T2> o2, final Func2<? super T1, ? super T2, ? extends R> zipFunction) {
        return just(new Observable<?>[] { o1, o2 }).lift(new OperatorZip<R>(zipFunction));
}

這個最終也是需要調用lift的轉化方法,lift方法真好用;注意這裏傳的Observable[],和from不同,just後續會直接會拿Observable[]去轉化,而不會把這個數組拆開;看下具體方法

public OperatorZip(Func2 f) {
        this.zipFunction = Functions.fromFunc(f);
}

public static <T0, T1, R> FuncN<R> fromFunc(final Func2<? super T0, ? super T1, ? extends R> f) {
        return new FuncN<R>() {
            @SuppressWarnings("unchecked")
            @Override
            public R call(Object... args) {
                if (args.length != 2) {
                    throw new RuntimeException("Func2 expecting 2 arguments.");
                }
                return f.call((T0) args[0], (T1) args[1]);
            }
        };
}

發現這裏會把zipFunction計算出的最終結果返回,如果是同一主線程還比較好理解,但如果多個異步,這塊是怎麼保證所有結果的同步呢;我們看下這個類的詳細

public final class OperatorZip<R> implements Operator<R, Observable<?>[]> {
    @Override
    public Subscriber<? super Observable[]> call(final Subscriber<? super R> child) {
        final Zip<R> zipper = new Zip<R>(child, zipFunction);
        final ZipProducer<R> producer = new ZipProducer<R>(zipper);
        final ZipSubscriber subscriber = new ZipSubscriber(child, zipper, producer);

        child.add(subscriber);
        child.setProducer(producer);
        
        return subscriber;
    }
}

其中Zip這個類會存放我們傳進來的Subscriber,變量名字爲child,這個後面要用到

同樣,我們挑重點看,關心ZipSubscriber的方法;同樣我們只挑出onNext的執行方法

 public void onNext(Observable[] observables) {
            if (observables == null || observables.length == 0) {
                child.onCompleted();
            } else {
                started = true;
                zipper.start(observables, producer);
            }
 }

public void start(@SuppressWarnings("rawtypes") Observable[] os, AtomicLong requested) {
            final Object[] subscribers = new Object[os.length];
            for (int i = 0; i < os.length; i++) {
                InnerSubscriber io = new InnerSubscriber();
                subscribers[i] = io;
                childSubscription.add(io);
            }
            this.requested = requested;
            this.subscribers = subscribers; // full memory barrier: release all above
            for (int i = 0; i < os.length; i++) {
                os[i].unsafeSubscribe((InnerSubscriber) subscribers[i]);
            }
}

這裏會把數組裏面的每個Observable都拆出來,並依次註冊InnerSubscriber,也是就每塊處理仍然都是獨立的

final class InnerSubscriber extends Subscriber{
    ...
  public void onNext(Object t) {
       try {
              items.onNext(t);
           } catch (MissingBackpressureException e) {
              onError(e);
           }
            tick();
  }
}

items是創建的RxRingBuffer對象

public class RxRingBuffer implements Subscription{
     public void onNext(Object o) throws MissingBackpressureException {
          ...
        synchronized (this) {
            Queue<Object> q = queue;
            if (q != null) {
                mbe = !q.offer(on.next(o));
            } else {
                iae = true;
            }
        }
        ...
    }
}

這個會創建一個Queue隊列去存放獲得的數據,後面會通過peek方法判斷這個queue裏面是否有值

注意到這個tick方法,每個InnerSubscriber的onNext都會執行到這裏;我們挑出重點看

        ...
final int length = subscribers.length;
        ...
 while (true) {
      final Object[] vs = new Object[length];
      boolean allHaveValues = true;
      for (int i = 0; i < length; i++) {
        RxRingBuffer buffer = ((InnerSubscriber) subscribers[i]).items;
        Object n = buffer.peek();

        if (n == null) {
             allHaveValues = false;
             continue;
          }

        if (buffer.isCompleted(n)) {
             child.onCompleted();
             childSubscription.unsubscribe();
             return;
        } else {
             vs[i] = buffer.getValue(n);
     }

         ...
     if (requested.get() > 0 && allHaveValues) {
         try {
            child.onNext(zipFunction.call(vs));
            requested.decrementAndGet();
            emitted++;
           } catch (Throwable e) {
                Exceptions.throwOrReport(e, child, vs);
                return;
          }

        ...
}

這裏有個while循環,當所有的Observable都正常回調值,也就是vs這個數組被填滿後,再把這個數組返給zipFunction處理,最後把處理後的值返給我們定義的Subscriber;所以即使我們發出多個網絡請求,最後也能正確處理

例子

 Log.e(TAG, "zip start " );
        Observable<Integer> observable1 = Observable.just(1).map(new Func1<Integer, Integer>() {
            @Override
            public Integer call(Integer integer) {
                try {
                    Thread.sleep(1000);
                }catch (Exception e){}
                return integer;
            }
        }).subscribeOn(Schedulers.io());
        Observable<Boolean> observable2 = Observable.just(true).map(new Func1<Boolean, Boolean>() {
            @Override
            public Boolean call(Boolean aBoolean) {
                try {
                    Thread.sleep(2000);
                }catch (Exception e){}
                return aBoolean;
            }
        }).subscribeOn(Schedulers.io());
        Observable.zip(observable1, observable2, new Func2<Integer, Boolean, String>() {
            @Override
            public String call(Integer o, Boolean o2) {
                return o + ":" + o2;
            }
        }).subscribe(new Action1<String>() {
            @Override
            public void call(String o) {
                Log.e(TAG, "result = " + o);
            }
        });

這裏有兩個Observable,sleep不同時間,結果上會以時間最長的那個爲準

01-30 15:38:03.135 E/Main: zip start 
01-30 15:38:05.156 E/Main: result = 1:true
public static <R> Observable<R> zip(Iterable<? extends Observable<?>> ws, FuncN<? extends R> zipFunction)

和之前的一樣,這個傳入的是一個集合;但必須是同類型的Observable集合

 Observable<Integer> observable1 = Observable.just(1);
        Observable<Integer> observable2 = Observable.just(2);
        List<Observable<Integer>> list = Arrays.asList(observable1, observable2);
        Observable.zip(list, new FuncN<String>() {
            @Override
            public String call(Object... args) {
                int result = 0;
                for (Object obj : args) {
                    result += ((Integer) obj).intValue();
                }
                return "result=" + result;
            }
        }).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                Log.e(TAG, s);
            }
});

輸出結果

E/Main: result=3
public static <R> Observable<R> zip(Observable<? extends Observable<?>> ws, final FuncN<? extends R> zipFunction) {
        return ws.toList().map(new Func1<List<? extends Observable<?>>, Observable<?>[]>() {

            @Override
            public Observable<?>[] call(List<? extends Observable<?>> o) {
                return o.toArray(new Observable<?>[o.size()]);
            }

        }).lift(new OperatorZip<R>(zipFunction));
    }

這個方法會把傳入Observable轉成集合再轉成數組,之後的流程和上面描述的基本一致

amb

public static <T> Observable<T> amb(Observable<? extends T> o1, Observable<? extends T> o2)
...... 超過兩個及以上的方法暫不寫出,因爲流程是一樣的
public static <T> Observable<T> amb(Iterable<? extends Observable<? extends T>> sources)

還是以最簡單的兩個爲例

public static <T> Observable<T> amb(Observable<? extends T> o1, Observable<? extends T> o2) {
        return create(OnSubscribeAmb.amb(o1, o2));   }

public static <T> OnSubscribe<T> amb(Observable<? extends T> o1, Observable<? extends T> o2) {
        List<Observable<? extends T>> sources = new ArrayList<Observable<? extends T>>();
        sources.add(o1);
        sources.add(o2);
        return amb(sources);
}
 public static <T> OnSubscribe<T> amb(final Iterable<? extends Observable<? extends T>> sources) {
        return new OnSubscribeAmb<T>(sources);
    }

我們發現最終還是會走到上面的第二個方法,而且值得注意的是,這些泛型都必須保持一致

我們挑重點看

public final class OnSubscribeAmb<T> implements OnSubscribe<T>{
     @Override
    public void call(final Subscriber<? super T> subscriber) {
        final Selection<T> selection = new Selection<T>();
        final AtomicReference<AmbSubscriber<T>> choice = selection.choice;
        ......
         for (Observable<? extends T> source : sources) {
            if (subscriber.isUnsubscribed()) {
                break;
            }
            AmbSubscriber<T> ambSubscriber = new AmbSubscriber<T>(0, subscriber, selection);
            selection.ambSubscribers.add(ambSubscriber);
            AmbSubscriber<T> c;
            if ((c = choice.get()) != null) {
                // Already chose one, the rest can be skipped and we can clean up
                selection.unsubscribeOthers(c);
                return;
            }
            source.unsafeSubscribe(ambSubscriber);
        }
    }
}

所有的Observable都會註冊一個AmbSubscriber,而這個裏面傳入了我們最終輸出的subscriber;也是這個內部會處理我們的輸出方法,這裏的choice後面也會用到,仍然挑重點看

private static final class AmbSubscriber<T> extends Subscriber<T> {
    ......
    @Override
    public void onNext(T t) {
       if (!isSelected()) {
           return;
       }
       subscriber.onNext(t);
   }
   @Override
   public void onCompleted() {
       if (!isSelected()) {
           return;
       }
          subscriber.onCompleted();
       }
   @Override
   public void onError(Throwable e) {
       if (!isSelected()) {
           return;
        }
          subscriber.onError(e);
      }

private boolean isSelected() {
    if (chosen) {
         return true;
       }
       if (selection.choice.get() == this) {
        chosen = true;
        return true;
     } else {
       if (selection.choice.compareAndSet(null, this)) {
           selection.unsubscribeOthers(this);
           chosen = true;
           return true;
          } else {
            selection.unsubscribeLosers();
            return false;
           }
       }
   }
}

也就是說,只要接收到一次數據,就會給choice賦值,之後只有這一個Subscriber會正常返回true,也就是正常分發;之後的全部返回false,並且全部解除註冊;

unsubscribeLosers,顧名思義,失敗的全部解除;

amb其實就是一種競爭的隊列,第一個到達的會正常返回,之後的全部銷燬

例子

Log.e(TAG, "amb start ");
        Observable observable1 = Observable.just(1).subscribeOn(Schedulers.io()).map(new Func1<Integer, Integer>() {
            @Override
            public Integer call(Integer o) {
                try {
                    Thread.sleep(2000);
                } catch (Exception e) {
                }
                return o;
            }
        });
        Observable observable2 = Observable.just(2).subscribeOn(Schedulers.io()).map(new Func1<Integer, Integer>() {
            @Override
            public Integer call(Integer o) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
                return o;
            }
        });
        Observable.amb(observable1, observable2).subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.e(TAG, "result= " + o);
            }
        });

第一個sleep時間比第二個要長,第二個要先到達,第一個會被取消掉;輸出結果

01-30 16:23:38.681 5595-5595 E/Main: amb start 
01-30 16:23:39.705 5595-5616 E/Main: result= 2

combineLatest

public static <T1, T2, R> Observable<R> combineLatest(Observable<? extends T1> o1, Observable<? extends T2> o2, Func2<? super T1, ? super T2, ? extends R> combineFunction)
......
public static <T, R> Observable<R> combineLatest(List<? extends Observable<? extends T>> sources, FuncN<? extends R> combineFunction)
public static <T, R> Observable<R> combineLatest(Iterable<? extends Observable<? extends T>> sources, FuncN<? extends R> combineFunction)

以兩個的爲例

public static <T1, T2, R> Observable<R> combineLatest(Observable<? extends T1> o1, Observable<? extends T2> o2, Func2<? super T1, ? super T2, ? extends R> combineFunction) {
        return combineLatest(Arrays.asList(o1, o2), Functions.fromFunc(combineFunction));
}
public static <T, R> Observable<R> combineLatest(List<? extends Observable<? extends T>> sources, FuncN<? extends R> combineFunction) {
        return create(new OnSubscribeCombineLatest<T, R>(sources, combineFunction));
}

這個方法最終會組成list調用下面的list的方法

public final class OnSubscribeCombineLatest<T, R> implements OnSubscribe<R> {
public OnSubscribeCombineLatest(Iterable<? extends Observable<? extends T>> sourcesIterable,
            FuncN<? extends R> combiner) {
        this(null, sourcesIterable, combiner, RxRingBuffer.SIZE, false);
}
 public void call(Subscriber<? super R> s) {
        Observable<? extends T>[] sources = this.sources;
        int count = 0;
        ......
        if (sources == null) {
            if (sourcesIterable instanceof List) {
                List list = (List)sourcesIterable;
                sources = (Observable[])list.toArray(new Observable[list.size()]);
                count = sources.length;
            } else {
                   ......
               }
            }
        } else {
            count = sources.length;
        }
        if (count == 0) {
            s.onCompleted();
            return;
        }
        LatestCoordinator<T, R> lc = new LatestCoordinator<T, R>(s, combiner, count, bufferSize, delayError);
        lc.subscribe(sources);
    }
}

傳入的Observable會轉成一個數組source,計算出數組的大小count,然後這裏會把subscrbier和combiner轉化方法都保存到LastestCoordinator裏處理,再看下這個具體類

static final class LatestCoordinator<T, R> extends AtomicInteger implements Producer, Subscription {
  static final Object MISSING = new Object();  
  public LatestCoordinator(Subscriber<? super R> actual, 
                FuncN<? extends R> combiner, 
                int count, int bufferSize, boolean delayError) {
            this.actual = actual;
            this.combiner = combiner;
            this.count = count;
            this.bufferSize = bufferSize;
            this.delayError = delayError;
            this.latest = new Object[count];
            // latest集合會全部以MISSION填充,其實都是一樣的
            Arrays.fill(latest, MISSING);
            this.subscribers = new CombinerSubscriber[count];
            this.queue = new SpscLinkedArrayQueue<Object>(bufferSize);
            this.requested = new AtomicLong();
            this.error = new AtomicReference<Throwable>();
        }
    public void subscribe(Observable<? extends T>[] sources) {
            Subscriber<T>[] as = subscribers;
            int len = as.length;
            for (int i = 0; i < len; i++) {
                as[i] = new CombinerSubscriber<T, R>(this, i);
            }
            lazySet(0); // release array contents
            actual.add(this);
            actual.setProducer(this);
            for (int i = 0; i < len; i++) {
                if (cancelled) {
                    return;
                }
                sources[i].subscribe(as[i]);
            }
        }
}

這裏會創建兩個和Observable數同樣大小的數組 latest和subscribers;

其中latest會存放每個Observable回調的結果,存放的內容和每個Observable是一一對應的,也就是每個Obs只對應一個,如果有新的結果,則會替換掉之前的;

subscribers會把當前即LatestCoordinator和此次要創建的subscriber索引i傳入,後面sources的註冊的subscriber一一對應;就是每個Observable都會對應一個唯一的CombinerSubscriber,索引值就是上面的 i

static final class CombinerSubscriber<T, R> extends Subscriber<T> {
@Override
public void onNext(T t) {
            if (done)  return;
            parent.combine(nl.next(t), index);
        }
@Override
public void onError(Throwable t) {
            ......
            parent.onError(t);
            done = true;
            parent.combine(null, index);
        }
@Override
public void onCompleted() {
            if (done) {
                return;
            }
            done = true;
            parent.combine(null, index);
        }

 void combine(Object value, int index) {
            CombinerSubscriber<T, R> combinerSubscriber = subscribers[index];
            int activeCount;
            int completedCount;
            int sourceCount;
            boolean empty;
            boolean allSourcesFinished;
            synchronized (this) {
              //數目等於傳入的Observable對象數
                sourceCount = latest.length;
                Object o = latest[index];
                activeCount = active;
                if (o == MISSING) {
                    active = ++activeCount;
                  //最開始這個一直是相等的,除非其中一個走了onError
                  //否則這個數最後疊加會和sourceCount相等
                }
                completedCount = complete;
                if (value == null) {
                    complete = ++completedCount;
                  //完成數,正常走complete的value都是空的(Error也是空的)
                } else {
                    latest[index] = combinerSubscriber.nl.getValue(value);
                    //每走一次onNext都會賦一次值,也就是會把之前的替換掉
                }
                allSourcesFinished = activeCount == sourceCount;
                //所有的Observable都至少回調了一次onNext,也就是latest填滿了
                empty = completedCount == sourceCount 
                        || (value == null && o == MISSING);
                //全部結束(包括異常) 或者 其中出現了一次異常結果
                //這個不太好理解,我們反推,否命題就是 : 事件還在繼續分發而且沒有發生過一次異常

                if (!empty) {
                    if (value != null && allSourcesFinished) {
                        //latest被填充滿,同時此次回調的值不爲空
                        //也就是latest集合中的最後一個被填充後,後續再來值都會走這個方法
                        queue.offer(combinerSubscriber, latest.clone());
                    } else
                    if (value == null && error.get() != null) {
                        done = true;
                    }
                } else {
                    done = true;
                }
            }
            if (!allSourcesFinished && value != null) {
                combinerSubscriber.requestMore(1);
                return;
            }
            drain();
        }
}

那麼重點就在drain方法了,摘出重點

void drain() {
            if (getAndIncrement() != 0) {
                return;
            }
            final Queue<Object> q = queue;
            final Subscriber<? super R> a = actual;
            int missed = 1;
            for (;;) {
                ......
                while (requestAmount != 0L) {
                    CombinerSubscriber<T, R> cs = (CombinerSubscriber<T, R>)q.peek();
                    boolean empty = cs == null;
                    ......                     
                    if (empty) {
                        break;
                    }
                    q.poll();
                    Object[] array = (Object[])q.poll();
                    if (array == null) {
                        cancelled = true;
                        cancel(q);
                        a.onError(new IllegalStateException("Broken queue?! Sender received but not the array."));
                        return;
                    }
                    R v;
                    try {
                        v = combiner.call(array);
                    } catch (Throwable ex) {
                        cancelled = true;
                        cancel(q);
                        a.onError(ex);
                        return;
                    }
                    a.onNext(v);
                  ......
                }
                ......
                missed = addAndGet(-missed);
                if (missed == 0) {
                    break;
                }
            }
        }

當queue集合不爲空的時候,摘出此時拷貝的latest副本,把這個副本的集合用我們定義的combiner方法處理後再傳給我們將要處理的subscriber;

所以對於多個的分發,Observable內子分發個數不一定要保持一樣,後續計算結果也並不需要同時抵達,這個是和zip的很大區別,zip方法要求分發數必須相同,否則後續的結果接受不到

例子

 Log.e(TAG, "combineLastest start");
        Observable observable1 = Observable.just(1,2).subscribeOn(Schedulers.io()).map(new Func1() {
            @Override
            public Object call(Object o) {
                try {
                    Thread.sleep(2000);
                } catch (Exception e) {
                }
                return o;
            }
        });
        Observable observable2 = Observable.just(true, false).subscribeOn(Schedulers.io()).map(new Func1() {
            @Override
            public Object call(Object o) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
                return o;
            }
        });
        Observable.combineLatest(observable1, observable2, new Func2<Integer, Boolean, String>() {
            @Override
            public String call(Integer o, Boolean o2) {
                return o + " : " + o2;
            }
        }).subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.e(TAG, "result= " + o);
            }
        });

作區分我做了sleep時間,實際輸出結果是

01-30 22:52:44.958 E/Main: combineLastest start
01-30 22:52:46.978 E/Main: result= 1 : true
01-30 22:52:46.982 E/Main: result= 1 : false
01-30 22:52:48.979 E/Main: result= 2 : false

我們發現接收到了三次,第一次要求是同時抵達;後續會按照上次的結果計算,第二次是false先抵達,然後取第一個obs1上次的1, 第三次則是2抵達,取obs2上次的false ; 這個的使用場景和我們登陸輸入賬號密碼有點類似

那我們如果改成 zip呢,輸出結果是

01-30 22:57:11.954 E/Main: result= 1 : true
01-30 22:57:13.956 E/Main: result= 2 : false

只有兩次,結果索引是匹配的,我們再把第一個obs刪掉一個數據,改成Observable.just(1),那麼輸出結果是

01-30 22:58:46.174 E/Main: result= 1 : true

結果就只剩一個了,因爲第二個索引個數不匹配

後面兩個方法和之前類似,變成了集合而已,而且也是泛型需要統一

concatEager

public static <T> Observable<T> concatEager(Observable<? extends T> o1, Observable<? extends T> o2) 
......
public static <T> Observable<T> concatEager(Iterable<? extends Observable<? extends T>> sources)
public static <T> Observable<T> concatEager(Iterable<? extends Observable<? extends T>> sources, int capacityHint)

仍然以兩個的爲例

public final class OperatorEagerConcatMap<T, R> implements Operator<R, T> {
@Override
public Subscriber<? super T> call(Subscriber<? super R> t) {
        EagerOuterSubscriber<T, R> outer = new EagerOuterSubscriber<T, R>(mapper, bufferSize, t);
        outer.init();
        return outer;
    }
}

static final class EagerOuterSubscriber<T, R> extends Subscriber<T> {
public EagerOuterSubscriber(Func1<? super T, ? extends Observable<? extends R>> mapper, int bufferSize,
                Subscriber<? super R> actual) {
            this.mapper = mapper;
            this.bufferSize = bufferSize;
            this.actual = actual;
            this.subscribers = new LinkedList<EagerInnerSubscriber<R>>();
            this.wip = new AtomicInteger();
   }
public void onNext(T t) {
            Observable<? extends R> observable;
            
            try {
                observable = mapper.call(t);
            } catch (Throwable e) {
                Exceptions.throwOrReport(e, actual, t);
                return;
            }
            EagerInnerSubscriber<R> inner = new EagerInnerSubscriber<R>(this, bufferSize);
            if (cancelled) {
                return;
            }
            synchronized (subscribers) {
                if (cancelled) {
                    return;
                }
                subscribers.add(inner);
            }
            if (cancelled) {
                return;
            }
            observable.unsafeSubscribe(inner);
            drain();
        }
}

這裏創建了一個LinkList存放後面註冊的EagerInnerSubscriber,按照順序添加,這個onNext裏面會依次回調添加進的Observable,並順序註冊上面的InnerSubscriber

static final class EagerInnerSubscriber<T> extends Subscriber<T> {
 final EagerOuterSubscriber<?, T> parent;
 final Queue<Object> queue;
@Override
public void onNext(T t) {
            //每次獲取到數據都會把這個數據添加到這個queue隊列中
            queue.offer(nl.next(t));
            parent.drain();
        }
@Override 
public void onCompleted() {
            done = true;
            parent.drain();
        }       
}

數據會存放到這裏的queue隊列裏

void drain() {
            if (wip.getAndIncrement() != 0) {
                return;
            }
            int missed = 1;
            ......
            final Subscriber<? super R> actualSubscriber = this.actual;
            for (;;) {
                ......  
                EagerInnerSubscriber<R> innerSubscriber;
                boolean outerDone = done;
                synchronized (subscribers) {
                    //按照註冊的順序取出第一個
                    innerSubscriber = subscribers.peek();
                }
                boolean empty = innerSubscriber == null;
                ......
                if (!empty) {
                    ......
                    Queue<Object> innerQueue = innerSubscriber.queue;
                    boolean innerDone = false;
                    for (;;) {
                        outerDone = innerSubscriber.done;
                        //判斷這個subscriber是否已經分發完成
                        //回調onComplete會把這個done設成ture
                        Object v = innerQueue.peek();
                        //取出這個innersubscriber中第一個數據
                        empty = v == null;
                        .......
                        if (outerDone) {
                            Throwable innerError = innerSubscriber.error;
                            if (innerError != null) {
                                cleanup();
                                actualSubscriber.onError(innerError);
                                return;
                            } else
                            if (empty) {
                                synchronized (subscribers) {
                                    subscribers.poll();
                                  //如果這個innerSubscriber已經回調onCompleted
                                  //同時裏面的queue數據已經被全部取出,就把這個對應的sub彈出
                                  //這樣下次取的就是按順序的第二個subscriber    
                                }
                                innerSubscriber.unsubscribe();
                                innerDone = true;
                                break;
                            }
                        }
                        if (empty) {
                            break;
                        }
                        innerQueue.poll();
                        //如果第一個數有值,則彈出queue的第一個數據,並把這個數據返給我們定義的subscriber
                        try {
                            actualSubscriber.onNext(nl.getValue(v));
                        } catch (Throwable ex) {
                            Exceptions.throwOrReport(ex, actualSubscriber, v);
                            return;
                        }
                       ......
                    }
                    ......
                    if (innerDone) {
                        //這個Observable已經完成,遍歷下一個
                        continue;
                    }    
                }
                missed = wip.addAndGet(-missed);
                if (missed == 0) {
                    return;
                }
            }
        }

每次獲得結果都會根據需求判斷是否要循環遍歷,如果正好是第一個註冊的則輸出,如果非首個註冊的,則緩存數據,等待第一個完成再輸出這個緩存數據

這個實際輸出結果和concat類似,不同的是concat是按照Observable順序依次執行,等第一個有結果後再去執行第二個;

這個方法是可以同時執行,每次取到結果時候進行判斷,保持結果依次發出

例子

Observable observable1 = Observable.just(1).subscribeOn(Schedulers.io()).map(new Func1() {
            @Override
            public Object call(Object o) {
                try {
                    Thread.sleep(2000);
                } catch (Exception e) {
                }
                Log.e(TAG,"obs1獲得了結果");
                return o;
            }
        });
        Observable observable2 = Observable.just(2).subscribeOn(Schedulers.io()).map(new Func1() {
            @Override
            public Object call(Object o) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                }
                Log.e(TAG,"obs2獲得了結果");
                return o;
            }
        });
        Observable.concatEager(observable1, observable2).subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.e(TAG, "result= " + o);
            }
        });

輸出結果是

01-31 00:19:23.597  E/Main: obs2獲得了結果
01-31 00:19:24.586  E/Main: obs1獲得了結果
01-31 00:19:24.586  E/Main: result= 1
01-31 00:19:24.586  E/Main: result= 2

同樣,如果我們換成concat方法,輸出則變成了

01-31 00:19:08.050  E/Main: obs1獲得了結果
01-31 00:19:08.050  E/Main: result= 1
01-31 00:19:09.054  E/Main: obs2獲得了結果
01-31 00:19:09.054  E/Main: result= 2

類似於我們的同步和異步概念

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章