Rxjava(结合类)-Zip

通过一个函数将多个Observables的发射物结合到一起,基于这个函数的结果为每个结合体发 射单个数据项。

Zip 操作符返回一个Obversable,它使用这个函数按顺序结合两个或多个Observables发射 的数据项,然后它发射这个函数返回的结果。它按照严格的顺序应用这个函数。它只发射与 发射数据项最少的那个Observable一样多的数据


demo

        Observable.zip(Observable.just(1, 2, 3), Observable.just("a", "b", "c", "d"), new Func2<Integer, String,
                String>() {
            @Override
            public String call(Integer integer, String s) {
                return s + integer;
            }
        }).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                System.out.println(s);
            }
        });
输出:

a1
b2
c3


看一下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) {
        return just(new Observable<?>[] { o1, o2 }).lift(new OperatorZip<R>(zipFunction));
    }

just会创建一个i额ScalarSynchronousObservable类型的observable,然后调用lift传递了OperatorZip,以demo中的函数作为OperatorZip的参数

subsuribe最终调用OnSubscribeLift的call

public void call(Subscriber<? super R> o) {
        try {
            Subscriber<? super T> st = RxJavaHooks.onObservableLift(operator).call(o);
            try {
                // new Subscriber created and being subscribed with so 'onStart' it
                st.onStart();
                parent.call(st);
            } catch (Throwable e) {
                // localized capture of errors rather than it skipping all operators
                // and ending up in the try/catch of the subscribe method which then
                // prevents onErrorResumeNext and other similar approaches to error handling
                Exceptions.throwIfFatal(e);
                st.onError(e);
            }
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            // if the lift function failed all we can do is pass the error to the final Subscriber
            // as we don't have the operator available to us
            o.onError(e);
        }
    }
operator就是前面的OperatorZip,这里调用它的call

    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;
    }
以传进来的function和child创建一个Zip,child是我们的订阅者,然后以Zip创建了一个ZipProducer和一个ZipSubscriber,并把ZipSubscriber返回

回到OnSubscribeLift的call,然后调用

parent.call(st)
parent就是我们前面创建的ScalarSynchronousObservable

 @Override
        public void call(Subscriber<? super T> s) {
            s.setProducer(createProducer(s, value));
        }
这里创建了一个producer

  static <T> Producer createProducer(Subscriber<? super T> s, T v) {
        if (STRONG_MODE) {
            return new SingleProducer<T>(s, v);
        }
        return new WeakSingleProducer<T>(s, v);
    }
这里返回WeakSingleProducer

setProducet最终调用上面WeakSingleProducer的request

public void request(long n) {
            if (once) {
                return;
            }
            if (n < 0L) {
                throw new IllegalStateException("n >= required but it was " + n);
            }
            if (n == 0L) {
                return;
            }
            once = true;
            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();
        }
actual是前面创建的ZipSubscriber

value是我们demo中的两个observable

调用actual的onNext

@Override
        public void onNext(Observable[] observables) {
            if (observables == null || observables.length == 0) {
                child.onCompleted();
            } else {
                started = true;
                zipper.start(observables, producer);
            }
        }
zipper就是我们前面创建的Zip,调用它的start

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]);
            }
        }
创建InnerSubscriber并添加到childSubscription

然后分别调用Observalbe的unsafeSubscribe,最终调用到OnSubscribeFromArray的

  public void call(Subscriber<? super T> child) {
        child.setProducer(new FromArrayProducer<T>(child, array));
    }
这里创建一个FromArrayProducer,setProducer最终调用前面producer的request

 public void request(long n) {
            if (n < 0) {
                throw new IllegalArgumentException("n >= 0 required but it was " + n);
            }
            if (n == Long.MAX_VALUE) {
                if (BackpressureUtils.getAndAddRequest(this, n) == 0) {
                    fastPath();
                }
            } else
            if (n != 0) {
                if (BackpressureUtils.getAndAddRequest(this, n) == 0) {
                    slowPath(n);
                }
            }
        }
这里调用slowPath

 void slowPath(long r) {
            final Subscriber<? super T> child = this.child;
            final T[] array = this.array;
            final int n = array.length;

            long e = 0L;
            int i = index;

            for (;;) {

                while (r != 0L && i != n) {
                    if (child.isUnsubscribed()) {
                        return;
                    }

                    child.onNext(array[i]);

                    i++;

                    if (i == n) {
                        if (!child.isUnsubscribed()) {
                            child.onCompleted();
                        }
                        return;
                    }

                    r--;
                    e--;
                }

                r = get() + e;

                if (r == 0L) {
                    index = i;
                    r = addAndGet(e);
                    if (r == 0L) {
                        return;
                    }
                    e = 0L;
                }
            }
        }
    }
child是InnerSubscriber,调用它的onNext

     public void onNext(Object t) {
                try {
                    items.onNext(t);
                } catch (MissingBackpressureException e) {
                    onError(e);
                }
                tick();
            }
这里的item是RxRingBuffer

public void onNext(Object o) throws MissingBackpressureException {
        boolean iae = false;
        boolean mbe = false;
        synchronized (this) {
            Queue<Object> q = queue;
            if (q != null) {
                mbe = !q.offer(NotificationLite.next(o));
            } else {
                iae = true;
            }
        }

        if (iae) {
            throw new IllegalStateException("This instance has been unsubscribed and the queue is no longer usable.");
        }
        if (mbe) {
            throw new MissingBackpressureException();
        }
    }
这里会把当前值入队列

回到前面tick

void tick() {
            final Object[] subscribers = this.subscribers;
            if (subscribers == null) {
                // nothing yet to do (initial request from Producer)
                return;
            }
            if (getAndIncrement() == 0) {
                final int length = subscribers.length;
                final Observer<? super R> child = this.child;
                final AtomicLong requested = this.requested;
                do {
                    while (true) {
                        // peek for a potential onCompleted event
                        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();
                                // we need to unsubscribe from all children since children are
                                // independently subscribed
                                childSubscription.unsubscribe();
                                return;
                            } else {
                                vs[i] = buffer.getValue(n);
                            }
                        }
                        // we only emit if requested > 0 and have all values available
                        if (requested.get() > 0 && allHaveValues) {
                            try {
                                // all have something so emit
                                child.onNext(zipFunction.call(vs));
                                // we emitted so decrement the requested counter
                                requested.decrementAndGet();
                                emitted++;
                            } catch (Throwable e) {
                                Exceptions.throwOrReport(e, child, vs);
                                return;
                            }
                            // now remove them
                            for (Object obj : subscribers) {
                                RxRingBuffer buffer = ((InnerSubscriber) obj).items;
                                buffer.poll();
                                // eagerly check if the next item on this queue is an onComplete
                                if (buffer.isCompleted(buffer.peek())) {
                                    // it is an onComplete so shut down
                                    child.onCompleted();
                                    // we need to unsubscribe from all children since children are independently subscribed
                                    childSubscription.unsubscribe();
                                    return;
                                }
                            }
                            if (emitted > THRESHOLD) {
                                for (Object obj : subscribers) {
                                    ((InnerSubscriber) obj).requestMore(emitted);
                                }
                                emitted = 0;
                            }
                        } else {
                            break;
                        }
                    }
                } while (decrementAndGet() > 0);
            }

        }

这里的subscribers就是前面创建的InnerSubscriber的数量,child就是我们的订阅者

然后获取InnerSubscriber的items(RxRingBuffer)如果值为空,说明当前还不是在最后一个obserable发射数据,直接返回,如果是最后一个Observable发射数据,allHaveValues为true接着调用

 child.onNext(zipFunction.call(vs));

这里会先调用 前面zipFunction,传递一个数组值

child是SafeSubscriber类型,最终onNext调用到我们的订阅者的onNext













评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值