2016-06-06

  RxJava是最近两年火起来的一个框架,核心是异步,但是对于我来说印象最深的是响应式编程的思想。最近刚好想把自己的项目改成用RxJava实现,所以就研究了下。抛物线和大头鬼两位大牛也讲解的很详细和形象,其实RxJava里除了这种响应式的编程思想不太好理解外,操作符也是比较难理解的一部分。响应式编程思想不是三言两语就能讲清楚,想学习的人也不是通过看几遍blog就能学会的。我这里主要是讲操符,通过分解的方式一步一步带领大家看着到底是怎么回事,就以常用的map为例。

首先看一段伪代码:

Observable.create(new Observable.Onsubscrible(){  //------------ Observable one
  @overridepublic object call(…subscriber){  //----------------------call one
     ……subscriber.onNext();  //-------------- onNext one
     …….
}
}).map(new Func1(){ // ----------------------map 操作后返回的为Observable two
  @overridePublic object call(…){   //-----------------------------call two
     …….
}}).subscrible(new Subscriber(){@overridepublic void onCompleted(){}@overridePublic void onError(){}@overridePublic void onNext(){  //-------------------------onNext two
     …….}
});

我将剖析上面的一段RxJava代码。为了一步一步的把问题描述清楚,我们先把上面的代码简化如下,定义observableTemp变量:

observableTemp.subscrible(new Subscriber (){…..});

其中ObservableTemp为:

observableTemp =
observable.create(new Observable.Onsubscrible(){  //------------ Observable one
  @overridepublic object call(…subscriber){  //----------------------call one
     ……subscriber.onNext();  //-------------- onNext one
     …….
}
}).map(new Func1(){ // ----------------------map 操作后返回的为Observable two
  @overridePublic object call(…){   //-----------------------------call two
     …….
}});

   

第一步,我们先解析subscrible到底做了什么

  hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);

这是整个subscrible方法的核心。onSubscribeStart返回的是observable.onSubscribe,而observable.onSubscribe是传入参数,为this对象。所以可以把subcrible方法的主要功能简化为:

 ObservableTemp. onSubscribe.call(new Subscriber (){….});

举例说明下:如果

ObservableTemp =

Observable.create(new Observable.Onsubscrible(){

@override

public object call(…subscriber){  //---------------1-1

subscriber.onNext();

}

})

那么ObservableTemp. onSubscribe.call(new Subscriber (){….});分解如下:

ObservableTemp. onSubscrib = Observable.Onsubscrible()

这里的1-1传入值按照我们刚才简化后形式,应该是new Subscriber ()。那么整个就成了:

new Observable.Onsubscrible(){

@override

public object call(…subscriber){

……

subscriber.onNext();

……..

}

}.call(new Subscriber (){….});

这里的call就是调用的@override的call方法,所以这里进一步分解:

public object call(){

……

new Subscriber (){….}.onNext();

……..

}

看明白了吗?其实整个一大段代码只是执行了Subscriber里的onNext方法。

相信看到这里已经明白了subscribe方法的作用了。但是如果把ObservableTemp展开呢?也就是还原到开头的那段代码,又干了什么事情呢?请看第二步的分解

  

第二步,map到底做了什么

  我们已经知道ObservableTemp. onSubscribe.call(new Subscriber (){….});其实是通过ObservableTemp里的Onsubscrible.call方法直接调用Subscriber的onNext方法。那么加入map后,到底是怎么一种调用关系呢?Map字面的意思应该是个映射操作,那到底是不是字面上的映射?如果是映射,到底谁和谁之间的映射呢?

为了方便说明,我们还是把开头第一段代码做个简化,简化为:

ObservableTemp.map(new Func1(){…}).subcrible(new Subscriber(){…});

其中ObservableTemp 就是一个简单的对象创建和赋值过程了:

Observable.create(new Observable.Onsubscrible(){ @overridepublic object call(…subscriber){ ……subscriber.onNext();…….
}
}); // 没有什么理解上的难度

map的操作代码是:

lift(new OperatorMap<T, R>(func));

lift是RxJava里核心,几乎大部分Observable操作都是需要用到lift方法。A.lift(Operator op)返回的是一个新的Observable,新Observable中的OnSubscribe为OnSubscribeLift。

ObservableTemp.map(new Func1(){…}).subcrible(new Subscriber(){…});

就变成了:

new Observable(new OnSubscribeLift(){
@overridePublic object call(…){  …….
}
}).subcrible(new Subscriber(){…}); // ------------------------- 2-2

是不是很眼熟,Yes, 就是第一步里简化的步骤。那么这里关键的部分来了,OnSubscribeLift里的call做了什么,如果我们把这个搞清楚了,那么map就自然而然的就清楚了。

OnSubscribeLift里的call主要有两行代码:

Subscriber<? super T> st = hook.onLift(operator).call(o);
parent.call(st);

这里的operator,o ,parent以及 st到底是什么呢?

因为这里的o是OnSubscribeLift里call方法传入的参数,由2-2可以知道,o其实代表的是new Subscriber()。

再看operator,由代码可以看出:

public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {return lift(new OperatorMap<T, R>(func));}

这里的operator就是指经过OperatorMap包装过的Operator对象:new OperatorMap<T, R>(new Func1());而hook.onLift(operator)返回的就是operator,那么上面两句代码可以看成:

Subscriber<? super T> st = (new OperatorMap<T, R>(new Func1())).call(o);
parent.call(st);

OperatorMap里的call做了三件事情:

MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
o.add(parent);
return parent;

把 new subscriber()和new Func1()(就是transformer对象)通过MapSubscriber封装起来。然后新的Subcriber(MapSubscriber对象)放入订阅列表中,以便最后一起把订阅对象释放。同时返回新的Subcriber。

根据上述的,

Subscriber<? super T> st = (new OperatorMap<T, R>(new Func1())).call(o);
parent.call(st);

可以看成:

Subscriber<? super T> st  = new MapSubscriber<T, R>(o, transformer);
parent.call(st);

而parent是传入的参数,指ObservableTemp.onSubscribe,也就是开头代码中的Observable one。

进一步上述两行代码可以看成:

Subscriber<? super T> st  = new MapSubscriber<T, R>(o, transformer);
(new Observable.Onsubscrible(){  //------------ Observable one
  @overridepublic object call(…subscriber){  //----------------------call one
     ……subscriber.onNext();  //-------------- onNext one
     …….
}
}).call(st);

这里的override里的call参数为new MapSubscriber<T, R>(o, transformer); new MapSubscriber<T, R>(o, transformer).onNext主要代码为:

@Overridepublic void onNext(T t) {result = mapper.call(t);actual.onNext(result);}

Mapper就是transformer对象,也就是new Func1(),而actual就是new subscriber()。也就是说:把Observable one里的类型经过new Func1().call的方法转换成另外一个Subscriber,最后调用new Subscriber的onNext方法。

所以map整个过程就清楚了:
A.map(B).subscribe(C) 就是:

先通过map方法,把A中想要转换的数据通过调用B里的call方法进行转换,最后把转换过的数据用C里的onNext方法进行处理。

我们抛开onCompleted和onError方法,

A.map(B).subscribe(C)  <==>  C.onNext (B.call(A.onNext()))

转载于:https://www.cnblogs.com/StephenWu/p/5565153.html

RxJava Map操作详解相关推荐

  1. python列表切片后得到剩余列表_python列表切片和嵌套列表取值操作详解

    python列表切片和嵌套列表取值操作详解 给出列表切片的格式: [开头元素::步长] # 输出直到最后一个元素,(最后一个冒号和步长可以省略,下同) [开头元素:结尾元素(不含):步长] # 其中, ...

  2. Kotlin 基础——Map集合详解

    Kotlin基础--Map集合详解 一.声明和创建Map集合 二.使用Map的方法 三.遍历Map四种方式 四.可变的Map Kotlin的Map集合用于保存key-value对,其也被分为可变的和不 ...

  3. jquery在html实现遍历,jQuery教程之jQuery遍历、HTML操作详解

    本篇文章探讨了jQuery教程之jQuery遍历.HTML操作详解,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入. < 什么是遍历? jQuery 遍历,意为"移 ...

  4. python输入参数改变图形_Python基于Tensor FLow的图像处理操作详解

    本文实例讲述了Python基于Tensor FLow的图像处理操作.分享给大家供大家参考,具体如下: 在对图像进行深度学习时,有时可能图片的数量不足,或者希望网络进行更多的学习,这时可以对现有的图片数 ...

  5. 第 5 章 Nova - 041 - Resize Instance 操作详解

    Resize Instance 操作详解 Resize 的作用是调整 instance 的 vCPU.内存和磁盘资源. Instance 需要多少资源是定义在 flavor 中的,resize 操作是 ...

  6. SVN的Windows和Linux客户端操作详解

    SVN的Windows和Linux客户端操作详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Windows客户端操作 1.安装SVN客户端 a>.去官网下载svn软件 ...

  7. python对输入的字符串进行解析_python数据类型_字符串常用操作(详解)

    这次主要介绍字符串常用操作方法及例子 1.python字符串 在python中声明一个字符串,通常有三种方法:在它的两边加上单引号.双引号或者三引号,如下: name = 'hello' name1 ...

  8. pythonpandas函数详解_对pandas中Series的map函数详解

    Series的map方法可以接受一个函数或含有映射关系的字典型对象. 使用map是一种实现元素级转换以及其他数据清理工作的便捷方式. (DataFrame中对应的是applymap()函数,当然Dat ...

  9. countif和sum套用_if函数嵌套countif、sumif函数实例操作详解 你需要学习了

    excel中if函数嵌套countif函数实例操作详解,需要了解if函数.countif函数.sumif函数字符串引用方式,isblank函数 操作方法 01 用扫描枪连接excel后将自动将货物名称 ...

  10. Java实现话术词槽匹配_桔子互动|百度UNIT操作详解(上篇)

    原标题:桔子互动|百度UNIT操作详解(上篇) 作者:令狐曦 文章简介: 本篇文章对UNIT的操作和注意事项进行详细说明,内容包括: 建立场景 配置对话单元/问答单元/高级设置 [配置对话单元] [配 ...

最新文章

  1. cenos7 阿里云数据库扩容步骤
  2. c++ softmax sigmoid
  3. 把一个dataset的表放在另一个dataset里面_使用中文维基百科语料库训练一个word2vec模型并使用说明...
  4. Python入门100题 | 第060题
  5. keras保存模型_onnx+tensorrt部署keras模型
  6. 【科普】boy and girl,你是不是对算法工程师有误解
  7. 从零开始学习docker(十二)介绍Docker Compose基本使用
  8. 如何进行良好的程序设计(1)
  9. 四大算法解决最短路径问题(Dijkstra+Bellman-ford+SPFA+Floyd)
  10. POJ - 3342 Party at Hali-Bula(树形dp)
  11. 2020 ICPC 济南 F. Gcd Product
  12. C语言(CED)钢条最优切割收益
  13. 【工具相关】Web-Sublime Text2的用法(一)
  14. bzoj千题计划141:bzoj3532: [Sdoi2014]Lis
  15. Notepad++软件的下载与安装步骤(图文详解)
  16. ubuntu 20.04 安装 QQ 和 Wechat 及其卸载, 解决微信不能发图片, 输入框输入中文显示方块问题
  17. python爬虫爬取深交所数据
  18. Visual Studio日文乱码解决方法
  19. DNS是什么,修改几个数字就能提升网速?(转载)
  20. 通过OpenCV实现虚拟键盘

热门文章

  1. oracle 高级用法, DECODE 排序, OVER(PARTITION BY X ORDER BY Y DESC) 开窗函数
  2. Flutter实战视频-移动电商-18.首页_火爆专区后台接口调试
  3. Java基础梳理(一)
  4. java nio广播服务器
  5. Java中RMI远程调用demo
  6. XJTUOJ13 (数论+FFT)
  7. 任正非为什么向两千多年前的李冰父子学习?
  8. (1)Jenkins Linux环境下的简单搭建
  9. solr5.5.3+tomcat8部署
  10. ORACLE11.2.0.1升级到11.2.0.3