Rxjava - 异步设计思想

6 篇文章 0 订阅

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
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值