Обработка пустого ответа с помощью модификации и rxjava 2.x

При использовании rxjava 1.x я возвращал Observable<Void> для обработки пустого ответа от модификации:

@POST( "login" )
Observable<Void> getToken( @Header( "Authorization" ) String authorization,
                                       @Header( "username" ) String username,
                                       @Header( "password" ) String password );

Но поскольку rxjava 2.x ничего не испускает с Void, есть ли какая-нибудь хорошая практика для обработки этих пустых ответов?


person Samuel Eminet    schedule 09.01.2017    source источник


Ответы (4)


Completable был разработан для таких случаев. Он доступен начиная с RxJava 1.1.1. . Из официальных документов:

Представляет отложенное вычисление без какого-либо значения, а только указание на завершение или исключение. Класс следует той же схеме событий, что и Reactive-Streams: onSubscribe (onError | onComplete)?

Так что просто измените тип возвращаемого значения вашего метода:

@POST("login")
Completable getToken(@Header("Authorization") String authorization,
                     @Header("username")      String username,
                     @Header("password")      String password);

И перепишите своего подписчика, например:

apiManager.getToken(auth, name, pass)
    ...
    .subscribe(() -> {
        //success
    }, exception -> {
        //error
    });
person Maksim Ostrovidov    schedule 10.01.2017
comment
Это решение не сработает, если ответ может быть пустым при успехе или ошибкой с телом. - person dephinera; 09.07.2020
comment
Хорошее решение для запросов «выстрелил и забыл». Спасибо! - person Bugdr0id; 17.11.2020

Другое решение:

@POST("login")
Observable<Response<Void>> getToken(@Header("Authorization") String authorization,
                                    @Header("username") String username,
                                    @Header("password") String password);

Обновление: но я бы предпочел использовать Completable

person Leo Droidcoder    schedule 08.12.2017

Так что принятый ответ верен только частично. Completable будет работать в некоторых случаях, когда ожидается одно и только одно излучение, однако Completable будет излучать только один раз и не будет излучать после этого. Он похож на Single (за исключением того, что мы игнорируем передаваемое значение). Observable, с другой стороны, может излучать несколько раз. Итак, если наблюдаемый источник будет излучать несколько раз, ответ, по крайней мере, в RxJava2, - это излучение чего-то вроде Observable<Irrelevant> (где Irrelevant - статическое перечисление / класс) или, что еще лучше, Observable<Kotlin.Unit>.

public class Source {
    private PublishSubject<Kotlin.Unit> heartbeatOperation;
...
    void getHeartbeats() {
         while(getHeartbeatFromSource() != null) {
             hearbeatOperation.accept(Unit.INSTANCE);
         }  
    }

    public Observable<Unit> heartbeats() {
         return hearbeatOperation.hide();
    }
...
}


public class SourceConsumer {
   @Inject Source source;
...
    void printHearbeats() {
         source.heartbeats()
         .subscribe(unused -> {
             System.out.println("Heartbeat received at " + DateTime.now());
         });
    }
}
person NickJ    schedule 23.06.2020

Вы пробовали использовать Observable<Object>?

Это из официальной документации RxJava 2:

enum Irrelevant { INSTANCE; }

Observable<Object> source = Observable.create((ObservableEmitter<Object> emitter) -> {
   System.out.println("Side-effect 1");
   emitter.onNext(Irrelevant.INSTANCE);

   System.out.println("Side-effect 2");
   emitter.onNext(Irrelevant.INSTANCE);

   System.out.println("Side-effect 3");
   emitter.onNext(Irrelevant.INSTANCE);
});

source.subscribe(e -> { /* Ignored. */ }, Throwable::printStackTrace);
person Ionut Negru    schedule 10.01.2017