我的目标是从服务中获得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());
});
嵌套订阅有三个级别,关闭服务的语句出现在所有三个subscribe()中。
有什么方法可以减少数字订阅(回调)并使代码更易于阅读和理解吗?
谢谢!
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方法的一大优点(能够封装发射、异常和资源关闭处理),并简洁、简洁地重用它。