RxJava操作符源码解析(二)

       本篇文章是RxJava操作符系列的第二篇文章,我们今天来看看Map操作符与flatMap操作符。不过本篇文章是建立在前一篇基础上的,如果还没看过上一篇文章,请看RxJava操作符源码解析(一)

       我们还是从他们的使用开始理解:

  Map:

Observable.create(new ObservableOnSubscribe<String>() {
           @Override
           public void subscribe(ObservableEmitter<String> emitter) throws Exception {
               emitter.onNext("22");
           }
       }).map(new Function<String,Integer>() {

           @Override
           public Integer apply(String s) throws Exception {
               return Integer.valueOf(s);
           }
       }).subscribe(new Observer<Integer>() {
           @Override
           public void onSubscribe(Disposable d) {

           }

           @Override
           public void onNext(Integer o) {
               System.out.println("===>"+o);
           }

           @Override
           public void onError(Throwable e) {

           }

           @Override
           public void onComplete() {

           }
       });

可以看出来,map操作符的作用就是对对象的类型进行转换,在示例中,是将22这个字符串转换成整数22,那么他是怎么做到的呢,我们来看看他的内部原理。

       我们直接看示例中的map方法,

public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
        ObjectHelper.requireNonNull(mapper, "mapper is null");
        return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
    }

恩,很熟悉的代码,那么直接进入去看Observable类吧,

public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
    final Function<? super T, ? extends U> function;

    public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
        super(source);
        this.function = function;
    }

    @Override
    public void subscribeActual(Observer<? super U> t) {
        source.subscribe(new MapObserver<T, U>(t, function));
    }

    static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
        final Function<? super T, ? extends U> mapper;

        MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
            super(actual);
            this.mapper = mapper;
        }

        @Override
        public void onNext(T t) {
            if (done) {
                return;
            }

            if (sourceMode != NONE) {
                downstream.onNext(null);
                return;
            }

            U v;

            try {
                v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
            } catch (Throwable ex) {
                fail(ex);
                return;
            }
            downstream.onNext(v);
        }

        @Override
        public int requestFusion(int mode) {
            return transitiveBoundaryFusion(mode);
        }

        @Nullable
        @Override
        public U poll() throws Exception {
            T t = qd.poll();
            return t != null ? ObjectHelper.<U>requireNonNull(mapper.apply(t), "The mapper function returned a null value.") : null;
        }
    }
}

还记得在第一篇文章中说过,在subscibe方法的时候,会调用Observable的实现类的subscribeActual方法,那么我们就看ObservableMap的该方法,发现在该方法中是source.subscribe(new MapObserver<T,U>(t,function)),在这里可以看出来又将处理的逻辑放到MapObserver中去了,并且同时将Function当做参数传给他了,接下来就是看他的onNext方法了,有童鞋可能发现了,在这个类中为什么没有onError等方法,事实上,那些方法是被封装到BasicFuseableObserver中去了,是不是跟我在第一篇中说的封装很相似。我们继续onNext方法分析,在该方法中,首先是判断onNext是否执行过了,如果已经执行了,那么就不再进行第二次执行,接着往下走,先判断本次执行的融合模式是否是NONE,这个标记的作用主要是用来判断poll方法的执行时机的。再往下走,也就是这个操作符的最关键的部分了,对象类型的转换,我们看到MapObserver有两个泛型T与U,他们分别代表什么呢?T是代表传入的类型,U代表返回的类型,也就是发射的时候转成的类型,

v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");

这行代码就是关键代码,他通过mapper.apply方法将T对象转换成U对象,不过这个apply方法我们应该很熟悉的,是的,他就是Function类的面的,也就是我们在使用的时候用的匿名类,也就是说类型转换业务由我们自己去处理,这样功能性就比较强了,然后就是执行downstream.onNext方法将转换之后的对象传入到Observer的onNext方法中没这样就完成了类型转换过程了。

      flatMap:

        flatmap的重载方法很多种,在这里只讲带有三个参数的方法,其他的大家可以按照文章的思路自行去理解,没有很难。我们先来看看他的使用:

Observable.just("55555").flatMap(new Function<String, ObservableSource<Integer>>() {
            @Override
            public ObservableSource<Integer> apply(String s) throws Exception {
                System.out.println("===>onNext");
                return Observable.just(Integer.valueOf(s));
            }
        }, new Function<Throwable, ObservableSource<Integer>>() {
            @Override
            public ObservableSource<Integer> apply(Throwable throwable) throws Exception {
                System.out.println("===>error");
                return Observable.just(33);
            }
        }, new Callable<ObservableSource<? extends Integer>>() {
            @Override
            public ObservableSource<? extends Integer> call() throws Exception {
                System.out.println("===>Callable");
                return Observable.just(111);
            }
        }).map(new Function<Integer,Person>() {

            @Override
            public Person apply(Integer integer) throws Exception {
                return new Person("hahaa",integer);
            }
        }).subscribe(new Observer<Person>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Person o) {
                System.out.println("===>"+o);
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("===>111111111111111");
            }

            @Override
            public void onComplete() {
                System.out.println("===>1112222222222222");
            }
        });

在使用中我们发现他是结合map一起使用的,那么我们在这里可以更好的对比他们之间区别。这里我们先从subscribe方法讲起,还记得Observable的subscribe方法里面是怎么样的么?不记得?没关系,我们再来看一看,

public final void subscribe(Observer<? super T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);

            ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");

            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            ...
        }
    }

我们还记得调用的subscribeActual方法吧,他会去调用Observable的子类该方法了,在这里他调用的就是map返回的Observable的该方法,我们进入该方法

 public void subscribeActual(Observer<? super U> t) {
        source.subscribe(new MapObserver<T, U>(t, function));
    }

发现调用的是source的subscribeActual方法,那么我们再来看看这个source是什么?

public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
        super(source);
        this.function = function;
    }

他是在创建ObservableMap的时候传入的,那么他是从何传入的呢?我们看看ObservableMap的创建上面的subscribeActual方法,

public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
        ObjectHelper.requireNonNull(mapper, "mapper is null");
        return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
    }

这个传入的是一个this,很清楚了,他出传入的也是一个Observable,而这个Observable就是flatMap返回的。

        现在我们来看看flatMap方法了,

public final <R> Observable<R> flatMap(
            Function<? super T, ? extends ObservableSource<? extends R>> onNextMapper,
            Function<? super Throwable, ? extends ObservableSource<? extends R>> onErrorMapper,
            Callable<? extends ObservableSource<? extends R>> onCompleteSupplier) {
        ObjectHelper.requireNonNull(onNextMapper, "onNextMapper is null");
        ObjectHelper.requireNonNull(onErrorMapper, "onErrorMapper is null");
        ObjectHelper.requireNonNull(onCompleteSupplier, "onCompleteSupplier is null");
        return merge(new ObservableMapNotification<T, R>(this, onNextMapper, onErrorMapper, onCompleteSupplier));
    }

接着进入merge方法,

public static <T> Observable<T> merge(ObservableSource<? extends ObservableSource<? extends T>> sources) {
        ObjectHelper.requireNonNull(sources, "sources is null");
        return RxJavaPlugins.onAssembly(new ObservableFlatMap(sources, Functions.identity(), false, Integer.MAX_VALUE, bufferSize()));
    }

再去看看ObservableFlatMap类,

/**
 * Copyright (c) 2016-present, RxJava Contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
 * the License for the specific language governing permissions and limitations under the License.
 */

package io.reactivex.internal.operators.observable;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.*;

import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.exceptions.*;
import io.reactivex.functions.Function;
import io.reactivex.internal.disposables.DisposableHelper;
import io.reactivex.internal.functions.ObjectHelper;
import io.reactivex.internal.fuseable.*;
import io.reactivex.internal.queue.*;
import io.reactivex.internal.util.*;
import io.reactivex.plugins.RxJavaPlugins;

public final class ObservableFlatMap<T, U> extends AbstractObservableWithUpstream<T, U> {
    final Function<? super T, ? extends ObservableSource<? extends U>> mapper;
    final boolean delayErrors;
    final int maxConcurrency;
    final int bufferSize;

    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;
    }

    @Override
    public void subscribeActual(Observer<? super U> t) {

        if (ObservableScalarXMap.tryScalarXMapSubscribe(source, t, mapper)) {
            return;
        }

        source.subscribe(new MergeObserver<T, U>(t, mapper, delayErrors, maxConcurrency, bufferSize));
    }

    ...
}

上述中还记得我们说过会去调用flatMap返回的Observable的subscribeActual的方法吧,也就是调用这里了,而在这里,又有一个source,他是谁呢,如果上面大家都理解了,那肯定知道他是怎么来的了,这里就又要回到flatMap操作符那里了,我们看到那里有一个merge方法,而传入的是ObserableMapNotification,接着赋值给了ObservableFlatMap中的source,所以知道这个source是谁了吧,没错,他就是ObservableMapNotification返回的Obsevable,我们再去看看ObservableMapNotification的subscribeActual方法,

public void subscribeActual(Observer<? super ObservableSource<? extends R>> t) {
        source.subscribe(new MapNotificationObserver<T, R>(t, onNextMapper, onErrorMapper, onCompleteSupplier));
    }

看到这里又有一个source,那么他又是谁呢,没错,他就是just操作符返回的Observable,那么就会去调用他返回的Observable的该方法了,我们去看看Just操作符:

public static <T> Observable<T> just(T item) {
        ObjectHelper.requireNonNull(item, "The item is null");
        return RxJavaPlugins.onAssembly(new ObservableJust<T>(item));
    }
public final class ObservableJust<T> extends Observable<T> implements ScalarCallable<T> {

    private final T value;
    public ObservableJust(final T value) {
        this.value = value;
    }

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        ScalarDisposable<T> sd = new ScalarDisposable<T>(observer, value);
        observer.onSubscribe(sd);
        sd.run();
    }

    @Override
    public T call() {
        return value;
    }
}

相信大家看到了吧,他会进入到ObservableJust类的subscribeActual方法中,在这里我们看到,在Just方法中传入的value在他的构造函数中就已经赋值了,而我们可以通过它的call方法来获取这个值。我们还是接着看该类的subscribeActual方法,内部并不复杂,他会去调用ScalarDisposable的run方法,我们就去看看这个run方法干了什么:

@Override
        public void run() {
            if (get() == START && compareAndSet(START, ON_NEXT)) {
                observer.onNext(value);
                if (get() == ON_NEXT) {
                    lazySet(ON_COMPLETE);
                    observer.onComplete();
                }
            }
        }

这个方法中,首先是判断get()的值,这个get返回的默认的值是0,而START的值就是0所以返回的是true,接着就是compareAndSet方法,这个方法的作用是修改这个get里面的值,延伸一点,其实这里的get与set方法都是AtomicInteger类里面的,而且里面用UnSafe类来改变值的,至于说这里为什么要用UnSafe来操作这个变量,大家可以去google一下,其他的作用这里不讲,但是他在这里的作用我讲一下,因为我们在Rxjava中会涉及到线程的切换,那么此时就要保证同步问题,而这个UnSafe就是为了解决这个问题,这里的所用有点类似于volatile的作用。到这里,我们发现他的if语句返回的是true,那么我们就接着看observer.onNext方法,这个observer是谁呢?没错,就是我们上面ObservableMapNotification的observableActual的方法传入的MapNotificationObserver类,我们再来看看他的内部是什么样的:

public final class ObservableMapNotification<T, R> extends AbstractObservableWithUpstream<T, ObservableSource<? extends R>> {

    ...
    public ObservableMapNotification(
            ObservableSource<T> source,
            Function<? super T, ? extends ObservableSource<? extends R>> onNextMapper,
            Function<? super Throwable, ? extends ObservableSource<? extends R>> onErrorMapper,
                    Callable<? extends ObservableSource<? extends R>> onCompleteSupplier) {
        super(source);
        this.onNextMapper = onNextMapper;
        this.onErrorMapper = onErrorMapper;
        this.onCompleteSupplier = onCompleteSupplier;
    }

    @Override
    public void subscribeActual(Observer<? super ObservableSource<? extends R>> t) {
        source.subscribe(new MapNotificationObserver<T, R>(t, onNextMapper, onErrorMapper, onCompleteSupplier));
    }

    static final class MapNotificationObserver<T, R>
    implements Observer<T>, Disposable {
        final Observer<? super ObservableSource<? extends R>> downstream;
        final Function<? super T, ? extends ObservableSource<? extends R>> onNextMapper;
        final Function<? super Throwable, ? extends ObservableSource<? extends R>> onErrorMapper;
        final Callable<? extends ObservableSource<? extends R>> onCompleteSupplier;

        Disposable upstream;

        MapNotificationObserver(Observer<? super ObservableSource<? extends R>> actual,
                Function<? super T, ? extends ObservableSource<? extends R>> onNextMapper,
                Function<? super Throwable, ? extends ObservableSource<? extends R>> onErrorMapper,
                        Callable<? extends ObservableSource<? extends R>> onCompleteSupplier) {
            this.downstream = actual;
            this.onNextMapper = onNextMapper;
            this.onErrorMapper = onErrorMapper;
            this.onCompleteSupplier = onCompleteSupplier;
        }

        @Override
        public void onSubscribe(Disposable d) {
            if (DisposableHelper.validate(this.upstream, d)) {
                this.upstream = d;
                downstream.onSubscribe(this);
            }
        }

        @Override
        public void dispose() {
            upstream.dispose();
        }

        @Override
        public boolean isDisposed() {
            return upstream.isDisposed();
        }

        @Override
        public void onNext(T t) {
            ObservableSource<? extends R> p;

            try {
                p = ObjectHelper.requireNonNull(onNextMapper.apply(t), "The onNext ObservableSource returned is null");
            } catch (Throwable e) {
                Exceptions.throwIfFatal(e);
                downstream.onError(e);
                return;
            }

            downstream.onNext(p);
        }

        @Override
        public void onError(Throwable t) {
            ObservableSource<? extends R> p;

            try {
                p = ObjectHelper.requireNonNull(onErrorMapper.apply(t), "The onError ObservableSource returned is null");
            } catch (Throwable e) {
                Exceptions.throwIfFatal(e);
                downstream.onError(new CompositeException(t, e));
                return;
            }

            downstream.onNext(p);
            downstream.onComplete();
        }

        @Override
        public void onComplete() {
            ObservableSource<? extends R> p;

            try {
                p = ObjectHelper.requireNonNull(onCompleteSupplier.call(), "The onComplete ObservableSource returned is null");
            } catch (Throwable e) {
                Exceptions.throwIfFatal(e);
                downstream.onError(e);
                return;
            }

            downstream.onNext(p);
            downstream.onComplete();
        }
    }
}

我们看看MapNotificationObserver的onNext方法,发下他会返回onNextMapper.apply()返回的值,这个onNextMapper就是我们在调用flatMap操作符的时候传入的第一个参数,这个apply方法就是我们自己去实现的方法,回头看下,发现在apply方法里面我们返回的是Observable.just(Integer.valueOf(s))的值,也及时返回Observable.just("55555")的值,根据前面讲解的,我们知道他是一个ObservableJust类型,而在上述调用中,我们发现这个类型的返回值又被当做参数传给了downstream.onNext(p)方法中了,这个是downstream又是什么呢?对,没错,他就是我们上面ObservableFlatMap的observableActual的方法传入的MergeObserver类,ok,那现在去看看他的onNext方法吧,

static final class MergeObserver<T, U> extends AtomicInteger implements Disposable, Observer<T> {

        ...

        MergeObserver(Observer<? super U> actual, Function<? super T, ? extends ObservableSource<? extends U>> mapper,
                boolean delayErrors, int maxConcurrency, int bufferSize) {
            this.downstream = actual;
            this.mapper = mapper;
            this.delayErrors = delayErrors;
            this.maxConcurrency = maxConcurrency;
            this.bufferSize = bufferSize;
            if (maxConcurrency != Integer.MAX_VALUE) {
                sources = new ArrayDeque<ObservableSource<? extends U>>(maxConcurrency);
            }
            this.observers = new AtomicReference<InnerObserver<?, ?>[]>(EMPTY);
        }

        @Override
        public void onSubscribe(Disposable d) {
            if (DisposableHelper.validate(this.upstream, d)) {
                this.upstream = d;
                downstream.onSubscribe(this);
            }
        }

        @Override
        public void onNext(T t) {
            // safeguard against misbehaving sources
            if (done) {
                return;
            }
            ObservableSource<? extends U> p;
            try {
                p = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper returned a null ObservableSource");
            } catch (Throwable e) {
                Exceptions.throwIfFatal(e);
                upstream.dispose();
                onError(e);
                return;
            }

            if (maxConcurrency != Integer.MAX_VALUE) {
                synchronized (this) {
                    if (wip == maxConcurrency) {
                        sources.offer(p);
                        return;
                    }
                    wip++;
                }
            }

            subscribeInner(p);
        }

        @SuppressWarnings("unchecked")
        void subscribeInner(ObservableSource<? extends U> p) {
            for (;;) {
                if (p instanceof Callable) {
                    if (tryEmitScalar(((Callable<? extends U>)p)) && maxConcurrency != Integer.MAX_VALUE) {
                        boolean empty = false;
                        synchronized (this) {
                            p = sources.poll();
                            if (p == null) {
                                wip--;
                                empty = true;
                            }
                        }
                        if (empty) {
                            drain();
                            break;
                        }
                    } else {
                        break;
                    }
                } else {
                    InnerObserver<T, U> inner = new InnerObserver<T, U>(this, uniqueId++);
                    if (addInner(inner)) {
                        p.subscribe(inner);
                    }
                    break;
                }
            }
        }

      ...

        boolean tryEmitScalar(Callable<? extends U> value) {
            U u;
            try {
                u = value.call();
            } catch (Throwable ex) {
                Exceptions.throwIfFatal(ex);
                errors.addThrowable(ex);
                drain();
                return true;
            }

            if (u == null) {
                return true;
            }

            if (get() == 0 && compareAndSet(0, 1)) {
                downstream.onNext(u);
                if (decrementAndGet() == 0) {
                    return true;
                }
            } else {
                SimplePlainQueue<U> q = queue;
                if (q == null) {
                    if (maxConcurrency == Integer.MAX_VALUE) {
                        q = new SpscLinkedArrayQueue<U>(bufferSize);
                    } else {
                        q = new SpscArrayQueue<U>(maxConcurrency);
                    }
                    queue = q;
                }

                if (!q.offer(u)) {
                    onError(new IllegalStateException("Scalar queue full?!"));
                    return true;
                }
                if (getAndIncrement() != 0) {
                    return false;
                }
            }
            drainLoop();
            return true;
        }
     
       ...
    }

在这个onNext方法中,又调用mapper.apply方法并将返回值赋值给p,那么这个mapper又是什么呢,这个也要回到flatMap操作符中,其实他就是在创建ObservableFlatMap是的时候传入的Functions.identity(),那么他又有什么作用呢?这里不细讲了,他的作用就是将你传入的值原封不动的再返回来,所以说这个p的的类型跟t是一样的类型,只不过他们之间是继承关系,接着这个p又被当做参数传入到了subscribeInner方法中,而在该方法中,又会去调用tryEmitScalar方法,在该方法中首先会通过value.call()我们开始用just字符串传入的值取出来,也就是数字55555了(此时值的类型已经发生了改变),然后又调用downstream.onNext方法,此时这个downstream就不用过多介绍了吧,他就是ObservableMap的MapObserver了,后面的流程在map中已经介绍了,就不过多介绍了,但是这里要注意一点,因为在调用ScalarDisposable的run方法的时候,onNext方法虽然结束了,但是该run方法还未结束,会继续去走onComplete方法,当onComplete方法结束之后,我们整个流程就结束了。我们的流程就这样打通了,不知道各位童鞋是否理解了呢?

map与flatMap:

我们看到map返回的是一个简单的Object对象,但是这个对象如果为复合型的话,那么map虽然也能操作,但是代码写起来依旧会比较繁琐,或者说开发者自己还要写很多逻辑代码,这个时候就可以使用flatmap了,因为他返回的是一个Observable对象,那么他就可以反复去操作对象,比如像学校的学生,每个学生不仅有基本的姓名,年龄等信息,还有学科成绩等信息,如果这个时候我们要输出每一科的成绩,这个时候用flatmap进过变化就可以直接输出来,而不用像map一样还需要在onNext方法中进行循环处理每个学生的成绩了。这样flatmap在官网中解释的flatmap可以一对多的性质(数据被分成n份)。

总结

在flatMap操作符中,不知道大家发现没有,我们在subscribe的时候,这个订阅事件流向是这样的:ObservableMap--->ObservableFlatMap--->ObservableMapNotification--->ObservableJust,然后事件的返回结果的流向又是这样的:ObservableJust--->ObservableMapNotification--->ObservableFlatMap--->ObservableMap--->自定义的匿名类的Observer。这不是一个典型的观察者模式吗,也提现出了RxJava的核心思想,响应式编程!!!

这就是今天介绍的map与flatmap,我没有像其他文章一样用流程图来介绍他们的原理,而是从代码角度去解释,因为我觉得图看的再多,不如通过代码真正去实践一下,这样我们就会对他们的原理理解更加深刻,用起来也会更加得心应手!!!如果文章有什么不对的地方或者需要完善的地方,欢迎大家评论指正,谢谢!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值