作者博客
http://www.jianshu.com/u/c50b715ccaeb
前言
好久不见朋友们,最近一段时间在忙工作上的事情,没来得及写文章,这两天正好有点时间,赶紧写下了这篇教程,免得大家说我太监了。
正题
先来回顾一下上上节,我们讲Flowable的时候,说它采用了响应式拉的方式,我们还举了个叶问打小日本的例子,再来回顾一下吧,我们说把上游看成小日本, 把下游当作叶问, 当调用Subscription.request(1)时, 叶问就说我要打一个! 然后小日本就拿出一个鬼子给叶问, 让他打, 等叶问打死这个鬼子之后, 再次调用request(10), 叶问就又说我要打十个! 然后小日本又派出十个鬼子给叶问, 然后就在边上看热闹, 看叶问能不能打死十个鬼子, 等叶问打死十个鬼子后再继续要鬼子接着打。
但是不知道大家有没有发现,在我们前两节中的例子中,我们口中声称的响应式拉并没有完全体现出来,比如这个例子:
虽然我们在下游中是每次处理掉了一个事件之后才调用request(1)去请求下一个事件,也就是说叶问的确是在打死了一个鬼子之后才继续打下一个鬼子,可是上游呢?上游真的是每次当下游请求一个才拿出一个吗?从上上篇文章中我们知道并不是这样的,上游仍然是一开始就发送了所有的事件,也就是说小日本并没有等叶问打死一个才拿出一个,而是一开始就拿出了所有的鬼子,这些鬼子从一开始就在这儿排队等着被打死。
有个故事是这么说的:
楚人有卖盾与矛者,先誉其盾之坚,曰:“吾盾之坚,物莫能陷也。”俄而又誉其矛之利,曰:“吾矛之利,万物莫不陷也。”市人诘之曰:"以子之矛陷子之盾,何如?”其人弗能应也。众皆笑之。
没错,我们前后所说的就是自相矛盾了,这说明了什么呢,说明我们的实现并不是一个完整的实现,那么,究竟怎样的实现才是完整的呢?
我们先自己来想一想,在下游中调用Subscription.request(n)就可以告诉上游,下游能够处理多少个事件,那么上游要根据下游的处理能力正确的去发送事件,那么上游是不是应该知道下游的处理能力是多少啊,对吧,不然,一个巴掌拍不响啊,这种事情得你情我愿才行。
那么上游从哪里得知下游的处理能力呢?我们来看看上游最重要的部分,肯定就是FlowableEmitter了啊,我们就是通过它来发送事件的啊,来看看它的源码吧(别紧张,它的代码灰常简单):
FlowableEmitter是个接口,继承Emitter,Emitter里面就是我们的onNext(),onComplete()和onError()三个方法。我们看到FlowableEmitter中有这么一个方法:
long requested();
方法注释的意思就是当前外部请求的数量,哇哦,这好像就是我们要找的答案呢. 我们还是实际验证一下吧.
先来看同步的情况吧:
这个例子中,我们在上游中打印出当前的request数量,下游什么也不做。
我们先猜测一下结果,下游没有调用request(),说明当前下游的处理能力为0,那么上游得到的requested也应该是0,是不是呢?
来看看运行结果:
哈哈,结果果然是0,说明我们的结论基本上是对的。
那下游要是调用了request()呢,来看看:
这次在下游中调用了request(10),告诉上游我要打十个,看看运行结果: