Возникла у меня такая необходимость: выполнять операции последовательно, одну за другой. В принципе, довольно тривиальная задача, ничего особенного. За парой небольших исключений. Первое — каждый этап возвращает какой-то статус (типа success или код ошибки), и если выполнение операции не успешно, следующий этап выполняться не должен.

Первой мыслью у меня было использовать конструкцию столь же древнюю, сколь и джек на 3,5 мм. Я говорю про if-else. Но эта мысль практически сразу извинившись ушла, даже не дожидаясь какой-либо ее реализации. Даже без перевода ее на код можно сделать вывод, что выглядеть это будет ужасно, криво и неэстетично.

Вторая идея нашла реализацию, правда с очередностью выполнения задач я ничего придумать не успел. Все что я поменял от идея номер один — проверку результата операции переписал c if на throw exception. Выглядело это тоже несколько убого, но в принципе, это работало и с этим худо-бедно можно было смириться.

А потом я подумал «Эй, чувак, у тебя же RxJava добавлена уже проект, че ты ее не используешь-то?». Признаться по честности, я ее вкрутил в качестве таймера на SplashScreen (тоже покрасивше чем Handler смотрится, но — боже ты мой — кому это интересно как написано, лишь бы работало, да?) и больше ничего. Эта библиотека в очередном моем тестовом проекте не основная, так что пусть лежит себе и лежит.

Однако — ба-бамс — наступил ее звездный час. Немного полистав мануалы и погуглив проблемы, после трещотки клавиш родилось нечто следующее.

Вот это лично мне показалось куда более интересным (ну и трендовым, конечно, если вообще можно говорить о трендах в разработке).  Итак, поэтапно, что тут происходит:

  1. Observable получает список идшников операций (Observable.from)
  2. flatMap использую для генерации ошибки Observable.error. Честно говоря, другой способ вызова Subscriber.onError я не нашел.
    В случае success генерируется Observable, в который я передаю результат текущей операции
  3. Ну и остается объект Subscriber, который сохраняет результат каждой операции в самого себя. Если это последняя операция, то вызывается onComplete. OnError сам генерируется с помощью какой-то такой магии.

А теперь внимание вопрос — можно ли было упросить задачу используя Observable.zip()???