2016-09-23 117 views
0

首先,請原諒我的英語不好異步Web請求的最佳實踐...我會盡力使問題清晰...RxJava:用於編寫有依賴條件

我有一個對象一個最初,使用一個請求b,然後使用b請求ç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... }); 

這是正確的方法嗎?

+0

不,你是令人困惑的功能轉換與勢在必行的風格和使用可變對象'Zip在流中可能會導致問題。選擇不變性。你應該只用'obE.zipWith(obF,combiner)'來結束。 –

回答

3

假設你有一個可觀察的定義,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

我想你可以使用合併運營商處獲得乙

@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

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"; 
      }); 
     } 
    } 
} 
+0

如果你真的想要一個乾淨的代碼,習慣於使用lambda函數,而不是添加新的Func()。它使你的代碼無法讀懂夥伴 – paul

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 { 
}