Комбиниране на RxJava комплектуеми

1. Общ преглед

В този урок ще играем с типа Completable на RxJava , който представлява резултат от изчисление без действителна стойност.

2. RxJava зависимост

Нека включим зависимостта RxJava 2 в нашия проект Maven:

 io.reactivex.rxjava2 rxjava 2.2.2 

Обикновено можем да намерим най-новата версия на Maven Central.

3. Завършен тип

Изпълним е подобен на Observable с единственото изключение, че първият излъчва сигнали за завършване или грешка, но няма елементи. Класът Completable съдържа няколко удобни метода за създаване или получаване от различни реактивни източници.

Можем да създадем екземпляр, който завършва незабавно, като използваме Completable.complete () .

След това можем да наблюдаваме състоянието му, като използваме DisposableCompletableObserver :

Completable .complete() .subscribe(new DisposableCompletableObserver() { @Override public void onComplete() { System.out.println("Completed!"); } @Override public void onError(Throwable e) { e.printStackTrace(); } });

Освен това, ние можем да изгради Completable например от подлежащо на поискване изплащане, действие и Изпълнима :

Completable.fromRunnable(() -> {});

Също така, можем да получим изпълними екземпляри от други типове, като използваме или Completable.from (), или извикване ignoreElement () на самите източници Maybe, Single, Flowable и Observable :

Flowable flowable = Flowable .just("request received", "user logged in"); Completable flowableCompletable = Completable .fromPublisher(flowable); Completable singleCompletable = Single.just(1) .ignoreElement();

4. Свързване на комплектуеми

Можем да използваме верига на комплектуеми в много случаи на реално използване, когато се грижим само за успеха на операцията:

  • Действия „всичко или нищо“ като извършване на заявка PUT за актуализиране на отдалечен обект, последвано от актуализация на локална база данни след успеха
  • Постфактум регистриране и журналиране
  • Оркестрация на няколко действия, например стартиране на задача за анализ след приключване на действие за поглъщане

Ще поддържаме примери прости и агностични за проблеми. Помислете, че имаме няколко изпълними екземпляра:

Completable first = Completable .fromSingle(Single.just(1)); Completable second = Completable .fromRunnable(() -> {}); Throwable throwable = new RuntimeException(); Completable error = Single.error(throwable) .ignoreElement();

За да комбинираме два комплектуеми в един, можем да използваме оператора andThen () :

first .andThen(second) .test() .assertComplete();

Можем да веригираме толкова комплектуеми, колкото е необходимо. В същото време, ако поне един от източниците не успее да завърши, което води Completable ще се задейства onComplete () , както и :

first .andThen(second) .andThen(error) .test() .assertError(throwable);

Освен това, ако един от източниците е безкраен или не достигне onComplete по някаква причина, полученият Completable никога няма да задейства нитоComplete (), нито onError ().

Хубаво е, че все още можем да тестваме този сценарий:

... .andThen(Completable.never()) .test() .assertNotComplete();

5. Съставяне на поредица от изпълними елементи

Представете си, че имаме куп комплектуеми. Предполагаме, че трябва да регистрираме потребител в рамките на няколко отделни подсистеми.

За да обединим всички комплектуеми в един, можем да използваме семейството методи merge (). Операторът merge () позволява абониране за всички източници.

Полученият екземпляр завършва, след като всички източници са завършени . Освен това той завършва с onError, когато някой от източниците издава грешка:

Completable.mergeArray(first, second) .test() .assertComplete(); Completable.mergeArray(first, second, error) .test() .assertError(throwable);

Нека да преминем към малко по-различен случай на употреба. Да кажем, че трябва да изпълним действие за всеки елемент, получен от Flowable.

След това, ние искаме една единствена Completable както за завършването на предхождащият и всички действия, елемент на ниво. Операторът flatMapCompletable () идва на помощ в този случай:

Completable allElementsCompletable = Flowable .just("request received", "user logged in") .flatMapCompletable(message -> Completable .fromRunnable(() -> System.out.println(message)) ); allElementsCompletable .test() .assertComplete();

По същия начин горният метод е достъпен за останалите основни реактивни класове като Observable , Maybe или Single.

Като практически контекст за flatMapCompletable () , бихме могли да помислим за декориране на всеки елемент с някакъв страничен ефект. Можем да напишем запис в дневник за завършен елемент или да направим моментна снимка за съхранение при всяко успешно действие.

И накрая, може да се наложи да изградим Completable от няколко други източника и да го прекратим веднага щом някой от тях завърши. Тук операторите amb могат да помогнат.

Най- AMB представката е на кратко ръка за "съмнителен", което означава, несигурността, която Completable точно получава завършен. Например, ambArray ():

Completable.ambArray(first, Completable.never(), second) .test() .assertComplete();

Имайте предвид, че горният Completable може също да завърши с onError () вместо onComplete () в зависимост от това кой източник на comptable се прекратява първи:

Completable.ambArray(error, first, second) .test() .assertError(throwable);

Също така, след като първият източник прекрати, останалите източници са гарантирани да бъдат унищожени.

Това означава, че всички останали работещи Completables се спират чрез Disposable.dispose () и съответните CompletableObservers ще бъдат отписани.

По отношение на практически пример, можем да използваме amb (), когато предаваме архивен файл към няколко еквивалента отдалечени хранилища. И завършваме процеса, след като завърши първото най-добро архивиране или повтаряме процеса при грешка.

6. Заключение

В тази статия, ние прегледани накратко Completable вида на RxJava.

Започнахме с различни опции за получаване на Completable случаи и след това окован и съставен Completables с помощта на andThen (), сливане (), flatMapCompletable (), и AMB ... () оператори.

Можем да намерим източника за всички примерни кодове в GitHub.