Rxjava
来源:互联网 发布:蒙文软件ehshig 编辑:程序博客网 时间:2024/06/16 16:52
rxjava听了很多,因为一般都是自己做异步框架,所以没有用rxjava真正做过项目,顶多就写过一些demo。在写demo过程中,发现rxjava很麻烦,因此果断放弃了。最近有点空闲时间,想学习多一点框架的原理及应用,看了半天rxjava源码,虽然还不至于晕,但是还不是很理解为什么要那么做,刚好看到一篇博文,主要由简单代码模拟rxjava处理异步,发现我们平常写的callback还能这么写,在这里做一下记录。
先声明几个简单的类:
// 小车类public class Car { private String name; public Car(String name) { this.name = name; } public String getName() { return name; }}// 猫类public class Cat { private String name; public Cat(String name) { this.name = name; } public String getName() { return name; }}// 狗类public class Dog { private String name; public Dog(String name) { this.name = name; } public String getName() { return name; }}
// 魔术师类public class MagicService2 { public interface Callback <T> { void onSuccess(T result); void onError(Exception e); } // 把猫变成很多小车 void magicCat(Cat cat, Callback<List<Car>> callback) { // 魔术师比较菜,变的过程中可能需要时间,这里模拟异步 try { List<Car> carList = new ArrayList<>(); for (int i = 0; i < 10; i++) { carList.add(new Car(cat.getName() + i)); } callback.onSuccess(carList); } catch (Exception e) { callback.onError(e); } } // 把车变成狗 void magicCar(Car car, Callback<Dog> callback) { // 魔术师比较菜,变的过程中可能需要时间,这里模拟异步 callback.onSuccess(new Dog(car.getName())); }}
然后调用魔术师的2个魔术方法:
final MagicService2 service2 = new MagicService2();service2.magicCat(cat, new MagicService2.Callback<List<Car>>() { @Override public void onSuccess(List<Car> result) { service2.magicCar(result.get(result.size() - 1), new MagicService2.Callback<Dog>() { @Override public void onSuccess(Dog result) { Log.e(getClass().getName(), result.getName()); } @Override public void onError(Exception e) { Log.e(getClass().getName(), e.getMessage()); } }); } @Override public void onError(Exception e) { Log.e(getClass().getName(), e.getMessage()); }});
以上代码,相信很多人都这么写过,我之前就一直很反感这种多层异步代码,一直找不到方法改善。要是3层以上的异步,“迷之缩进”便会很明显,会影响我们阅读代码,必须改进。
由于魔术师的方法是无返回值的,所以只能在callback回调里面再写调用异步操作,这样就会造成“迷之缩进”。既然是因为无返回值造成的,我们不妨这么设计:
public class MagicService3 { public interface Callback <T> { void onSuccess(T result); void onError(Exception e); } public abstract class AsyncJob <T> { abstract void execute(Callback<T> callback); } AsyncJob<List<Car>> magicCat(final Cat cat) { return new AsyncJob<List<Car>>() { @Override void execute(Callback<List<Car>> callback) { try { List<Car> carList = new ArrayList<>(); for (int i = 0; i < 10; i++) { carList.add(new Car(cat.getName() + i)); } callback.onSuccess(carList); } catch (Exception e) { callback.onError(e); } } }; } AsyncJob<Dog> magicCar(final Car car) { return new AsyncJob<Dog>() { @Override void execute(Callback<Dog> callback) { callback.onSuccess(new Dog(car.getName())); } }; }}
调用时是这样的:
final MagicService3 service3 = new MagicService3();MagicService3.AsyncJob<List<Car>> job1 = service3.magicCat(cat);job1.execute(new MagicService3.Callback<List<Car>>() { @Override public void onSuccess(List<Car> result) { MagicService3.AsyncJob<Dog> job2 = service3.magicCar(result.get(result.size() - 1)); job2.execute(new MagicService3.Callback<Dog>() { @Override public void onSuccess(Dog result) { Log.e(getClass().getName(), result.getName()); } @Override public void onError(Exception e) { Log.e(getClass().getName(), e.getMessage()); } }); } @Override public void onError(Exception e) { Log.e(getClass().getName(), e.getMessage()); }});
这样下去也会产生“迷之缩进”。脑洞大一点,如果job1可以转化为job2,那该多好呀,的确可以:
public class MagicService4 { public interface Callback <T> { void onSuccess(T result); void onError(Exception e); } public interface Func <T, R> { R fun(T data); } public abstract class AsyncJob <T> { abstract void execute(Callback<T> callback); public <R> AsyncJob<R> map(final Func<T, R> func) { final AsyncJob<T> source = this; return new AsyncJob<R>() { @Override void execute(final Callback<R> callback) { source.execute(new Callback<T>() { @Override public void onSuccess(T result) { R data = func.fun(result); callback.onSuccess(data); } @Override public void onError(Exception e) { callback.onError(e); } }); } }; } public <R> AsyncJob<R> flapMap(final Func<T, AsyncJob<R>> func) { final AsyncJob<T> source = this; return new AsyncJob<R>() { @Override void execute(final Callback<R> callback) { source.execute(new Callback<T>() { @Override public void onSuccess(T result) { AsyncJob<R> data = func.fun(result); data.execute(new Callback<R>() { @Override public void onSuccess(R result) { callback.onSuccess(result); } @Override public void onError(Exception e) { callback.onError(e); } }); } @Override public void onError(Exception e) { callback.onError(e); } }); } }; } } AsyncJob<List<Car>> magicCat(final Cat cat) { return new AsyncJob<List<Car>>() { @Override void execute(Callback<List<Car>> callback) { try { List<Car> carList = new ArrayList<>(); for (int i = 0; i < 10; i++) { carList.add(new Car(cat.getName() + i)); } callback.onSuccess(carList); } catch (Exception e) { callback.onError(e); } } }; } AsyncJob<Dog> magicCar(final Car car) { return new AsyncJob<Dog>() { @Override void execute(Callback<Dog> callback) { callback.onSuccess(new Dog(car.getName())); } }; }}
这下调用就简单了:
final MagicService4 service4 = new MagicService4();MagicService4.AsyncJob<List<Car>> job3 = service4.magicCat(cat);MagicService4.AsyncJob<Car> job4 = job3.map(new MagicService4.Func<List<Car>, Car>() { @Override public Car fun(List<Car> data) { return data.get(data.size() - 1); }});MagicService4.AsyncJob<Dog> job5 = job4.flapMap(new MagicService4.Func<Car, MagicService4.AsyncJob<Dog>>() { @Override public MagicService4.AsyncJob<Dog> fun(Car data) { return service4.magicCar(data); }});job5.execute(new MagicService4.Callback<Dog>() { @Override public void onSuccess(Dog result) { Log.e(getClass().getName(), result.getName()); } @Override public void onError(Exception e) { Log.e(getClass().getName(), e.getMessage()); }});
这样,“迷之缩进”便解决了。这种组合思想实在太赞了,又学到东西了!!!
参考资料
NotRxJava懒人专用指南
阅读全文
0 0
- rxjava
- RXJava
- RXJava
- RXJava
- RxJava
- Rxjava
- RxJava
- RxJava
- Rxjava
- RxJava
- RxJava
- RxJava
- RxJava
- RxJava
- RxJava
- RxJava
- rxjava
- RxJava
- IntelliJ IDEA 创建 hello world Java web Maven项目遇到的问题
- 题目1517:链表中倒数第k个结点
- Apache Storm 的安装、配置及入门基础(二)
- MySql函数之 ISNULL()、NULLIF()和IFNULL()
- 解决 CentOS7 容器 Failed to get D-Bus connection: Operation not permitted
- Rxjava
- 子雨大数据之Spark入门教程
- JavaScript 风格指南(3)
- webpack学习
- Oracle 模糊查询的用法
- 水题集合
- 图片预加载之有序加载
- redis源码调试方法
- 喷水装置(一)