Est-il possible d'implémenter quelque chose comme le chaînage suivant en utilisant RxJava:
loginObservable()
.then( (someData) -> {
// returns another Observable<T> with some long operation
return fetchUserDataObservable(someData);
}).then( (userData) -> {
// it should be called when fetching user data completed (with userData of type T)
cacheUserData(userData);
}).then( (userData) -> {
// it should be called after all previous operations completed
displayUserData()
}).doOnError( (error) -> {
//do something
})
J'ai trouvé cette bibliothèque très intéressante, mais je n'arrive pas à comprendre comment enchaîner les demandes là où les autres dépendent des précédentes.
Bien sûr, RxJava prend en charge .map
qui fait cela. Depuis le wiki RxJava:
Fondamentalement, ce serait:
loginObservable()
.switchMap( someData -> fetchUserDataObservable(someData) )
.map( userData -> cacheUserData(userData) )
.subscribe(new Subscriber<YourResult>() {
@Override
public void onCompleted() {
// observable stream has ended - no more logins possible
}
@Override
public void onError(Throwable e) {
// do something
}
@Override
public void onNext(YourType yourType) {
displayUserData();
}
});
Ceci est le premier message lorsque Googling Observables de la chaîne RxJava donc je vais juste ajouter un autre cas courant où vous ne voudriez pas transformer les données que vous recevez, mais enchaînez-le avec une autre action (définir les données dans une base de données, par exemple). Utilisez .flatmap()
. Voici un exemple
mDataManager.fetchQuotesFromApi(limit)
.subscribeOn(mSchedulerProvider.io())
.observeOn(mSchedulerProvider.ui())
.onErrorResumeNext(Function { Observable.error<List<Quote>>(it) }) //OnErrorResumeNext and Observable.error() would propagate the error to the next level. So, whatever error occurs here, would get passed to onError() on the UI side
.flatMap { t: List<Quote> ->
//Chain observable as such
mDataManager.setQuotesToDb(t).subscribe({}, { e { "setQuotesToDb() error occurred: ${it.localizedMessage}" } }, { d { "Done server set" } })
Observable.just(t)
}
.subscribeBy(
onNext = {},
onError = { mvpView?.showError("No internet connection") },
onComplete = { d { "onComplete(): done with fetching quotes from api" } }
)
C'est RxKotlin2, mais l'idée est la même avec RxJava & RxJava2:
mDataManager.fetchQuotesFromApi()
.io()
et afficher les résultats sur le thread .ui()
.onErrorResumeNext()
s'assure que toute erreur rencontrée lors de la récupération des données est détectée dans cette méthode. Je veux terminer la chaîne entière quand il y a une erreur, donc je retourne une Observable.error()
.flatmap()
est la partie de chaînage. Je veux pouvoir définir toutes les données que j'obtiens de l'API dans ma base de données. Je ne transforme pas les données que j'ai reçues en utilisant .map()
, je fais simplement autre chose avec ces données sans le transformant.onError()
) abonnée avec onErrorResumeNext()
flatmap()
). Toute erreur qui se produit à travers cette observable sera [~ # ~] pas [~ # ~] propagée aux dernières méthodes subscribeBy()
, car il est géré à l'intérieur de la méthode subscribe()
à l'intérieur de la chaîne .flatmap()
.Le code provient de ce projet qui se trouve ici: https://github.com/Obaied/Sohan/blob/master/app/src/main/Java/com/obaied/ dingerquotes/ui/start/StartPresenter.kt
essayez d'utiliser scan ()
Flowable.fromArray(array).scan(...).subscribe(...)