如何减少API设计中的嵌套订阅(回调地狱)



我的目标是从服务中获得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方法的一大优点(能够封装发射、异常和资源关闭处理),并简洁、简洁地重用它。

相关内容

  • 没有找到相关文章

最新更新