web-dev-qa-db-fra.com

Comment utiliser l'opérateur d'intervalle RxJava

J'apprends à propos de l'opérateur RxJava, et j'ai trouvé que le code ci-dessous n'imprimait rien:

public static void main(String[] args) {

    Observable
    .interval(1, TimeUnit.SECONDS)
    .subscribe(new Subscriber<Long>() {
        @Override
        public void onCompleted() {
            System.out.println("onCompleted");
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("onError -> " + e.getMessage());
        }

        @Override
        public void onNext(Long l) {
            System.out.println("onNext -> " + l);
        }
    });
}

En tant que ReactiveX, interval

créer un observable qui émet une séquence d'entiers espacés d'un intervalle de temps particulier

Ai-je commis une erreur ou oublié quelque chose?

12
HuangDong.Li

Vous devez bloquer jusqu'à ce que l'observable soit consommé:

public static void main(String[] args) throws Exception {

    CountDownLatch latch = new CountDownLatch(1);

    Observable
    .interval(1, TimeUnit.SECONDS)
    .subscribe(new Subscriber<Long>() {
        @Override
        public void onCompleted() {
            System.out.println("onCompleted");
            // make sure to complete only when observable is done
            latch.countDown();
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("onError -> " + e.getMessage());
        }

        @Override
        public void onNext(Long l) {
            System.out.println("onNext -> " + l);
        }
    });

    // wait for observable to complete (never in this case...)
    latch.await();
}

Vous pouvez ajouter .take(10) par exemple pour voir l’observable terminé.

16
Reut Sharabani

Mettez Thread.sleep(1000000) après l'abonnement et vous le verrez fonctionner. Observable.interval fonctionne par défaut sur Schedulers.computation() afin que votre flux soit exécuté sur un thread autre que le thread principal.

5
Dave Moten

Comme ils vous le disent déjà, l'intervalle fonctionne de manière asynchrone. Vous devez donc attendre la fin de tous les événements.

Vous pouvez obtenir l'abonnement une fois que vous vous êtes abonné, puis utiliser TestSubcriber, qui fait partie de la plate-forme reactiveX, et qui vous donnera la possibilité d'attendre que tous les événements se terminent.

       @Test
public void testObservableInterval() throws InterruptedException {
    Subscription subscription = Observable.interval(1, TimeUnit.SECONDS)
              .map(time-> "item emitted")
              .subscribe(System.out::print,
                         item -> System.out.print("final:" + item));
    new TestSubscriber((Observer) subscription)
            .awaitTerminalEvent(100, TimeUnit.MILLISECONDS);
}

J'ai dans mon github d'autres exemples si vous avez besoin https://github.com/politrons/reactive/blob/master/src/test/Java/rx/observables/scheduler/ObservableAsynchronous.Java

0
paul