RxJava2实例源码浅析(2)-map

从最简单的例子着手,一步步看RxJava内部是如何封装调用的

Flowable.just(1, 2, 3)
                .map(new Function<Integer, String>() {
                    @Override
                    public String apply(@NonNull Integer integer) throws Exception {
                        return "hello"+integer;
                    }
                })
                .subscribe(new FlowableSubscriber<String>() {
                    @Override
                    public void onSubscribe(@NonNull Subscription subscription) {
                        subscription.request(Long.MAX_VALUE);
                    }

                    @Override
                    public void onNext(String s) {
                        Log.i(TAG, s);
                    }

                    @Override
                    public void onError(Throwable throwable) {
                    }

                    @Override
                    public void onComplete() {
                    }
                });

这个例子演示了map操作符,将1,2,3转换后输出“hello1”,“hello2”,“hello3”。


1.创建被观察者just(1, 2, 3)

@CheckReturnValue
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport("none")
    public static <T> Flowable<T> just(T item1, T item2, T item3) {
        ObjectHelper.requireNonNull(item1, "The first item is null");
        ObjectHelper.requireNonNull(item2, "The second item is null");
        ObjectHelper.requireNonNull(item3, "The third item is null");
        return fromArray(new Object[]{item1, item2, item3});
    }

可以看到just方法只是检查传入的参数是否非空,然后将参数组装数组,再调用fromArray

    @CheckReturnValue
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport("none")
    public static <T> Flowable<T> fromArray(T... items) {
        ObjectHelper.requireNonNull(items, "items is null");
        return items.length == 0?empty():(items.length == 1?just(items[0]):RxJavaPlugins.onAssembly(new FlowableFromArray(items)));
    }
这里直接创建返回FlowableFromArray对象,该对象保存了数组{1,2,3}。

2.map操作符

@CheckReturnValue
    @BackpressureSupport(BackpressureKind.PASS_THROUGH)
    @SchedulerSupport("none")
    public final <R> Flowable<R> map(Function<? super T, ? extends R> mapper) {
        ObjectHelper.requireNonNull(mapper, "mapper is null");
        return RxJavaPlugins.onAssembly(new FlowableMap(this, mapper));
    }

map操作符同样直接创建了FlowableMap对象并返回, FlowableMap保存FlowableFromArray对象自身和我们实现的Function接口。

public FlowableMap(Flowable<T> source, Function<? super T, ? extends U> mapper) {
        super(source);
        this.mapper = mapper;
    }
AbstractFlowableWithUpstream(Flowable<T> source) {
        this.source = (Flowable)ObjectHelper.requireNonNull(source, "source is null"); //这里source即FlowableFromArray
    }

3.订阅者FlowableSubscriber

这个接口上一篇有介绍过,就不说了。

4.订阅subscribe

subscribe内部真正执行订阅的方法是subscribeActual,打开 FlowableMap.subscribeActual方法看
protected void subscribeActual(Subscriber<? super U> s) {
        if(s instanceof ConditionalSubscriber) {
            this.source.subscribe(new FlowableMap.MapConditionalSubscriber((ConditionalSubscriber)s, this.mapper));
        } else {
            this.source.subscribe(new FlowableMap.MapSubscriber(s, this.mapper));
        }
    }

方法中首先判断传入的subscriber是否是ConditonalSubscriber,上面传入的并不是,所以执行下面一句。
创建MapSubscriber,它是FlowableMap的内部类(继承BasicFuseableSubscriber,最终继承自Subscriber),把subcriber和Function包装了进去。

public BasicFuseableSubscriber(Subscriber<? super R> actual) {
        this.actual = actual; //这里把我们自己实现的FlowableSubscriber保存起来
    }

this.source就是FlowableFromArray对象,所以这里又跳转到FlowableFromArray的subscribeActual方法。

public void subscribeActual(Subscriber<? super T> s) {
        if(s instanceof ConditionalSubscriber) {
            s.onSubscribe(new FlowableFromArray.ArrayConditionalSubscription((ConditionalSubscriber)s, this.array));
        } else {
            s.onSubscribe(new FlowableFromArray.ArraySubscription(s, this.array));
        }
    }
ArraySubscription(Subscriber<? super T> actual, T[] array) {
            super(array);
            this.actual = actual; //保存mapSubscriber
        }

和FlowableMap中类似,这里执行下面那句创建ArraySubscription,将m apSubscriber和{1, 2, 3}包装进去,然后回调mapSubscriber的onSubscribe方法并传入arraySubscription。

public final void onSubscribe(Subscription s) {
        if(SubscriptionHelper.validate(this.s, s)) {
            this.s = s;
            if(s instanceof QueueSubscription) {
                this.qs = (QueueSubscription)s;
            }

            if(this.beforeDownstream()) {
                this.actual.onSubscribe(this);
                this.afterDownstream();
            }
        }
    }

1)保存 a rraySubscription到this.s
2)instanceof比较,因为arraySubscription实现了QueueSubscription接口,所以这里为true,保存arraySubscription到this.qs
3)beforeDownstream方法内直接返回true,afterDownstream是空方法,所以直接执行onSubscribe方法,actual是我们自己创建的subscriber,即执行了下面这个回调

                    @Override
                    public void onSubscribe(@NonNull Subscription subscription) {
                        subscription.request(Long.MAX_VALUE);
                    }

执行request方法

public void request(long n) {
        this.s.request(n); //s即上一步保存的arraySubscription
    }
public final void request(long n) {
            if(SubscriptionHelper.validate(n) && BackpressureHelper.add(this, n) == 0L) {
                if(n == 9223372036854775807L) {
                    this.fastPath();
                } else {
                    this.slowPath(n);
                }
            }
        }

第一个if比较中数据校验和背压校验(RxJava2中具体的背压策略可以网上搜下专门的详解),这里都返回true,执行里面的代码。
前面传入的n是Long.MAX_VALUE,所以执行this.fastPath()

void fastPath() {
            Object[] arr = this.array;
            int f = arr.length;
            Subscriber a = this.actual; //actual即初始化时保存的mapSubscriber

            for(int i = this.index; i != f; ++i) {
                if(this.cancelled) { //默认是false
                    return;
                }

                Object t = arr[i];
                if(t == null) {
                    a.onError(new NullPointerException("array element is null"));
                    return;
                }

                a.onNext(t);
            }

            if(!this.cancelled) {
                a.onComplete();
            }
        }

可以看到这个方法中for循环依次取出数组中的数据传递给subscriber的onNext方法。
这里就是依次执行mapSubscriber.onNext(t)

public void onNext(T t) {
            if(!this.done) { //done默认是false
                if(this.sourceMode != 0) { //sourceMode默认是0
                    this.actual.onNext((Object)null);
                } else {
                    Object v;
                    try {
                        v = ObjectHelper.requireNonNull(this.mapper.apply(t), "The mapper function returned a null value.");
                    } catch (Throwable var4) {
                        this.fail(var4);
                        return;
                    }

                    this.actual.onNext(v);
                }
            }
        }

关键看this.mapper.apply(t),mapper就是我们例子中创建的Function

.map(new Function<Integer, String>() {
                    @Override
                    public String apply(@NonNull Integer integer) throws Exception {
                        return "hello"+integer;
                    }
                })

这里经过apply方法返回"hello"+t,返回值经过校验后传递给this.actual.onNext(v),这里的actual保存的是我们自己实现的FlowableSubscriber,因此最终调用了

@Override
 public void onNext(String s) {
     Log.i(TAG, s);
 }

接下来回到ArraySubscription中的fastPath方法,在for循环依次执行onNext后,就调用了onComplete方法,这里是 mapSubscriber.onComplete()

public void onComplete() {
        if(!this.done) {
            this.done = true;
            this.actual.onComplete();
        }
    }

可以看到最终调用了我们实现的 FlowableSubscriber的onComplete。

到这里整个执行调用过程就结束了。

PS:slowPath(n)方法内部使用while循环,依次取出数据传递给subscriber,退出时机由n和数据长度共同决定。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值