2015-12-17 17 views
6

Mi sento come se qualcuno avesse provato questo, ma non riesco a capire un modo carino di fare qualcosa se un osservabile richiede molto tempo.Come si mostra lo spinner se RxJava osservabile richiede troppo tempo?

Questo è il flusso che voglio.

Start a search. 
If the search takes longer than some time, 
    show a spinner or show progress bar. 
When finished do subscription action and hide spinner/progress bar. 

Il più vicino mi viene in mente è come uno Zip

manager.search(searchTerm) 
     .zip(Observable.Timer(1, TimeUnit.SECONDS)) 
     .subscribe(
      // if the search is non null then we are good 
      // if the long time is non 0 we need to show spinner 
     ); 

C'è qualcosa di meglio da fare? Ho provato tutto il giorno senza successo. In un mondo perfetto mi sento come vorrei qualcosa di simile

manager.search(searchTerm) 
     .timeout(i -> /* do timeout stuff */, 1, TimeUnit.SECONDS) 
     .subscribe(item -> /* do search result stuff */); 

risposta

5

È possibile farlo pubblicando la ricerca Observable attraverso il timeout:

Observable<Integer> source = Observable.just(1).delay(5, TimeUnit.SECONDS); 

source 
.doOnSubscribe(() -> System.out.println("Starting")) 
.publish(o -> 
    o.timeout(1, TimeUnit.SECONDS, Observable.<Integer>fromCallable(() -> { 
     System.out.println("Spinning..."); 
     return null; 
    })).ignoreElements().mergeWith(o) 
) 
.toBlocking() 
.subscribe(v -> { 
    System.out.println("Hide spinner if shown."); 
    System.out.println(v); 
}); 

Questo funziona suddividendo la fonte in due corsie a caldo: la prima corsia eseguirà un operatore timeout che, una volta scaduto, avvierà un altro Osservabile con l'effetto collaterale che mostra il controllo della rotazione. Uno dei modi è quello di usare fromCallable per questo e ignorarne il risultato (questo evita anche la duplicazione). La seconda corsia rimarrà invariata e unita alla corsia di timeout per fornire il valore effettivo.

+0

Dalla documentazione di 'BlockingObservable':" Ma è generalmente inappropriato per le applicazioni di produzione (se pensi di aver bisogno di usare un BlockingObservable questo di solito è un segno che dovresti ripensare alla tua progettazione). " Quindi quando si usa il blocco osservabile appropriato e quando no? – Than

+0

Direi che è ok usare BlockingObservable in alcuni casi, quando migliora davvero la leggibilità del tuo codice. – scana

+0

Ho usato 'BlockingObservable' qui a scopo dimostrativo, quindi l'app non si chiude prima di vedere tutte le linee di stampa. In produzione, non chiamare "toBlocking" e basta. – akarnokd

Problemi correlati