简体   繁体   中英

RxJava: How to prepend startWith() default emit EVERY TIME parent observable emits?

im trying to have a pattern, where my observable which produces some object, is transformed into domain events like Started, Success, Error emited around the observable producing, if that makes sense

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 contains a heavy action so I want to emit these state events, so UI can react accordingly (with success containing the extractedEpub object as you can see in the map)

What my problem is that, renderObservable contains combineLatest(), so it "stays open" and emit mutiple times in time, whenever its obervables emit.

So the flow of events is Started, Success, Succes ... Success.

I want it to be Started, Success, Started, Success .. etc. ie prepend Started event whever combineLatest emits, but my rx knowledge is insufficient.

Thanks

You could insert the following into the observable chain at the right place:

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

This will emit the Started event before every event that it receives.

Of course, you could add in some logic so that you don't issue Started if the event is Started , etc.

Ok Ive managed to figure it out. The key info I was missing is that right side of flatmap gets subscribed when left side emits. Therefore the startWith had to be moved to the right side of flatmap observable, that gets subscribed to when ever combineLatest emits

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()));
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM