我的目标是从服务中获取A,然后从A和服务中获取B.在完成B或发生异常之后,还需要关闭服务。
我想出了以下API:
Observable<Service> getService();
Observable<Integer> getA(Service service);
Observable<Integer> getB(Integer a, Service service)
我可以在下面使用它:
getService().subscribe(s -> {
getA(s).subscribe(a -> {
getB(a, s).subscribe(b -> {
doSomethingWith(b);
s.close();
}, r -> s.close());
}, r->s.close());
});
嵌套订阅有3个级别,关闭服务的语句出现在所有3个subscribe()中。
有没有办法减少订阅数量(回调)并使代码更容易阅读和理解?
谢谢!
答案 0 :(得分:4)
Observable.using
是您应该用来安全关闭资源的(包括早期取消订阅)。
为了避免嵌套回调问题,您只需要将自己限制为subscribe
次调用并使用flatMap
等适当的运算符。这种方式异常或取消将影响整个流而不仅仅是一个细分市场,您可以利用内置于Rx运营商的其他效率。
假设getRawService
调用返回服务而不是流,我会将代码重写为:
Observable
.using(
() -> getRawService(),
s ->
s.getA()
.flatMap(a -> s.getB(a))
.doOnNext(b -> doSomethingWith(b)),
s -> s.close())
.subscribe(subscriber);
上面的subscriber
会根据您的偏好报告错误,但是就此而言。
using
方法可以合并到您的getService
来电中,以便它返回此内容:
Observable.using(
() -> getRawService(),
s -> Observable.just(s),
s -> s.close());
从那以后,你不必担心关闭服务,所以它会是:
getService()
.map(s -> s.getA())
.flatMap(a -> s.getB(a))
.doOnNext(b -> doSomethingWith(b))
这种用法是RxJava方法的最佳优点之一(能够封装排放,异常和资源闭包处理)并简洁,简洁地重用它。