2017-10-06 65 views
1

即時通訊試圖有一個模式,在這裏我觀察到其產生的一些對象,轉化成域事件,如開始,成功,周圍觀察到的產emited錯誤,如果是有道理的RxJava:如何預先startWith()默認發射EVERY TIME父親observable發射?

public Observable<BookRenderingEvent> extractAndRenderObservable(String epubPath) { 
     return extractObservable(epubPath) 
       .flatMapObservable(extractedEpub -> renderObservable(extractedEpub) 
         .<BookRenderingEvent>map(renderedEpub -> new BookRenderingEvent.Success(renderedEpub)) 
         .onErrorReturn(t -> new BookRenderingEvent.Error()) 
         .startWith(new BookRenderingEvent.Started())); 
    } 

private Observable<RenderedEpub> renderObservable(ExtractedEpub extractedEpub) { 
     return Observable.combineLatest(readerConfigObservable(), pagerDimensionsObservable(), ..) 
        .switchMapSingle(foo -> doRenderObservable()) <--- heavy work 
        .map(bar -> new RenderedEpub(bar)) 
} 

renderObservable包含一個重行動所以我想發出這些狀態事件,所以UI可以作出相應的反應(成功包含提取的Eubub對象,就像你可以在地圖中看到的一樣)

我的問題是,renderObservable包含combineLatest(),所以它「保持打開「並且每當它的可發性發出時,都會及時發出多次。

因此,事件的流程是開始,成功,成功......成功。

我希望它被啓動,成功,開始,成功..等即在前面加上開始的活動,whever combineLatest發出,但我的RX知識是不夠的。

感謝

回答

1

你可以在正確的地方插入以下到觀察的鏈條:

.flatMap(event -> Observable.just(new BookRenderingEvent.Started(), event) 

這將它接收到的每個事件之前發出Started事件。

當然,你可以在一些邏輯添加,這樣你就不會發出Started如果事件是Started

+0

,你會把它嗎?我想出了一些想法..猜測它需要在combineLatest之後去觸發每個發射,但是接下來我又如何運行doRenderObservable? – urSus

+0

正確的地方你現在有'startWith()' –

+0

這會讓Success成爲之前開始 – urSus

0

好香港專業教育學院設法弄明白。我錯過的關鍵信息是當左側發射時,flatmap的右側被訂閱。因此,startWith不得不被轉移到flatmap觀察到的右側,是被訂閱當過combineLatest發出

public Observable<BookRenderingEvent> extractAndRenderObservable(String epubPath) { 
     return extractObservable(epubPath) 
       .flatMap(extractedEpub -> Observable.combineLatest(readerConfigObservable(), pagerDimensionsObservable(), ..) 
         .switchMap(foo -> renderObservable(extractedEpub) 
          .<BookRenderingEvent>map(renderedEpub -> new BookRenderingEvent.Success(renderedEpub)) 
          .onErrorReturn(t -> new BookRenderingEvent.Error()) 
          .startWith(new BookRenderingEvent.Started())); 
    }