interface Func<T, R> {
fun call(t: T): R
}
interface Subscriber<T> {
fun onNext(t: T)
}
class Observable<T>(val onSubscribe: OnSubscribe<T>) {
interface OnSubscribe<T> {
fun call(subscriber: Subscriber<in T>)
}
companion object {
fun <T> create(onSubscribe: OnSubscribe<T>): Observable<T> = Observable<T>(onSubscribe)
}
fun subscribe(subscriber: Subscriber<T>) {
onSubscribe.call(subscriber)
}
fun <R> map(func: Func<T, R>): Observable<R> {
return create(object : OnSubscribe<R> {
override fun call(subscriber: Subscriber<in R>) {
onSubscribe.call(object : Subscriber<T> {
override fun onNext(t: T) {
subscriber.onNext(func.call(t))
}
})
}
})
}
}
map方法的实质就是创建一个持有OnSubscribe<R>类型的Observable,在OnSubscribe<R>的call被调用的时候,调用当前Observable<T>持有的OnSubcribe<T>的
call方法,并定义一个简单的Subscriber<T>的对象在其onNext方法调用时,同步地调用Subscriber<R>的onNext方法,并传入由call方法生成R类型参数。
但是RxJava中的map方法实现好像和我们的写法相去甚远,原理没有错,但是由于RxJava中有各种各样的操作符,不只有map,所以Rxjava拆分了上述过程分为两个部分,
增加了代码的复用性。我们下面来看Rxjava如何利用Operator接口和lift方法来完成map的操作。
interface Operator<T, R> : Func<Subscriber<in T>, Subscriber<in R>>
class OperatorMap<T, R>(val tranform: Func<in T,out R>) : Operator<R, T> {
override fun call(origin: Subscriber<in R>): Subscriber<T> {
return object : Subscriber<T> {
override fun onNext(t: T) {
origin.onNext(tranform.call(t))
}
}
}
}
以上是根据Rxjava实现方法的简化实现,OperatorMap构造方法传入了用于将数据类型进行转换的Func<in T, out R>对象,call方法中定义了Subscriber<R>和
Subscriber<T>的联动方式,这也时Operater接口的关键之所在。
如果我们把此处的R当做最终需要的处理的类型,T当做中间类型,我们必须要构建一个Subscriber<T>来处理onSubscrible<T>的call方法,因为由在使用Rxjava
时由Subsribe方法最后传入的Subcriber<R>对象会处理R类型的参数,而中间类型T的接收并转发交付给Subcriber<R>的处理的Subscriber<T>需要RxJava框架来生成。
fun <R> lift(operator:Operator<R,T>): Observable<R> {
return create(object :OnSubscribe<R>{
override fun call(subscriber: Subscriber<in R>) {
val st = operator.call(subscriber)
onSubscribe.call(st)
}
})
lift方法也是按照Rxjava框架原理的核心实现,构造一个OnSubscribe<R>对象,其中的call方法会调用当前Observable<T>持有的OnSubscribe<T>的call方法,并
传入由MapOperator创建的Subscriber<T>作为参数。
fun <R> map(func: Func<in T, out R>): Observable<R> {
return lift(OperatorMap<T,R>(func))
}
这就是最终的map方法,看看是不是RxJava中的map方法一模一样。
文章的内容是有点儿老生常谈了,所以使用了kotlin的代码进行了实现,希望大家在看到代码后可以同时激发对kotlin的学习热情。:-D