RxJava:编写具有依赖性的异步Web请求的最佳实践

时间:2016-09-23 06:29:19

标签: callback rx-java

首先,请原谅我可怜的英语......我会尽量让问题清楚......

我最初有一个 a 对象,使用 a 来请求 b ,然后使用 b 来请求< strong> c 和 d ,这些对象之间的关系可以简化为:

        |-> c
a -> b -| 
        |-> d

我编写的代码如下:

B objB;
C objC;
D objD;

Observable.just(a)
    .doOnNext((b) -> objB = b)
    .map((a) -> getB(a))
    .map((b) -> getC(b))
    .subscribe((c) -> {
        objC = c;
        Observable.just(objB)
            .map((b) -> getD(b))
            .subscribe((d) -> objD = d);
    });

我该如何改善这个?

更新

感谢大家的回答。 实际上,实际情况比较复杂。数据流如下:

               |-> e
        |-> c -|-> f
a -> b -|-> d

我想使用的所有对象(b,c,d,e,f)。我将代码更改为:

class Zip {
    B b;
    C c;
    D d;
    E e;
    F f;
}

Observable<B> obB = Observable.fromCallable(this::getB).cache();
Observable<C> obC = obB.map(this::getC).cache();
Observable<D> obD = obB.map(this::getD);
Observable<E> obE = obC.map(this::getE);
Observable<F> obF = obC.map(this::getF);

obB
    .zipWith(obC, (b, c) -> {
        // side effects
        Zip zip = new Zip();
        zip.b = b;
        zip.c = c;
        return zip;
    })
    .zipWith(obD, (zip, d) -> {
        // side effects
        zip.d = d;
        return zip;
    })
    .zipWith(obE, (zip, e) -> {
        // side effects
        zip.e = e;
        return zip;
    })
    .zipWith(obF, (zip, f) -> {
        // side effects
        zip.f = f;
        return zip;
    })
    .subscribe((zip) -> { // update UI... });

这是正确的方法吗?

4 个答案:

答案 0 :(得分:3)

假设您有a,b,c和d的可观察定义:

A a = ...
Observable<B> b(A x) {...}
Observable<C> c(B x) {...}
Observable<D> d(B x) {...}
b(a)
 .flatMap(x -> 
    c(x).zipWith(d(x), (x,y) -> combine(x,y)))
 .subscribe(subscriber);

答案 1 :(得分:1)

我认为你可以在获得B

后使用合并运算符
@Test
public void dependencies(){
    Observable.just("a")
            .map(this::getB)
            .flatMap(c-> Observable.merge(getC(c), getD(c)))
            .subscribe(System.out::println);
}

String getB(String val){
    return val.concat("-b");
}
Observable<String> getC(String val){
    return Observable.just(val.concat("-c"));
}
Observable<String> getD(String val){
    return Observable.just(val.concat("-d"));
}

如果您想在此处了解有关RxJava的更多信息,请提供一些示例https://github.com/politrons/reactive

答案 2 :(得分:1)

这样的事情怎么样?就个人而言,代码更清晰,更易于维护。这篇https://medium.com/@p.tournaris/rxjava-one-observable-multiple-subscribers-7bf497646675#.3apipnkx4文章可能很有用。

public class SomeData {

    final Observable<String> observableA;
    final Observable<String> observableB;
    final Observable<String> observableC;
    final Observable<String> observableD;

    public final BehaviorSubject<Throwable> error = BehaviorSubject.create();

    public SomeData() {

        observableA = Observable.fromCallable(    // E.G. SOME API CALL
                () -> {
//                        throw new RuntimeException("Some Error");
                    return "A";
                })
                .onErrorResumeNext(new handleError())
                .cache();

        observableB = observableA               // SOME DATA MANIPULATION
                .flatMap((s) -> Observable.just(s + " B"))
                .onErrorResumeNext(new handleError())
                .cache();

        observableC = observableB              // FURTHER DATA PROCESSING
                .flatMap((s) -> Observable.just(s + " C"))
                .onErrorResumeNext(new handleError());

        observableD = observableB             // FURTHER DATA PROCESSING
                .flatMap((s) -> Observable.just(s + " D"))
                .onErrorResumeNext(new handleError());
    }

    public Observable<Throwable> getError() {
        return error;
    }

    private class handleError implements Func1<Throwable, Observable<? extends String>> {
        @Override
        public Observable<? extends String> call(Throwable throwable) {
            return Observable.just(throwable).map(throwable1 -> {
                error.onNext(throwable1);
                return "some error handling here";
            });
        }
    }
}

答案 3 :(得分:1)

我认为你可以通过flatMap和zip运算符的组合实现你想要的。这是一些代码:

public static void test() {
    A a = new A();
    a.getB()
            .flatMap(b -> Observable.zip(b.getC(), b.getD(), (c, d) -> c))
            .flatMap(c -> Observable.zip(c.getE(), c.getF(), (e, f) -> f))
            .subscribe();
}

public static class A {
    public Observable<B> getB() {
        return Observable.just(new B());
    }
}

public static class B {
    public Observable<C> getC() {
        return Observable.just(new C());
    }

    public Observable<D> getD() {
        return Observable.just(new D())
    }
}

public static class C {
    public Observable<E> getE() {
        return Observable.just(new E());
    }

    public Observable<F> getF() {
        return Observable.just(new F())
    }
}

public static class D {
}

public static class E {
}

public static class F {
}