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懒人专用指南

原创粉丝点击