2017-02-15 27 views
1

Я возиться с операторами гх и любопытно, почему just(null).repeat() не работает в качестве параметра для любой из встроенных операторов:Странное поведение наблюдаемых # повторе в реактивных расширений

Observable.interval(1, TimeUnit.SECONDS) 
    .sample(Observable.just(null).repeat()) 
    .subscribe(System.out::println); 

I ожидал, что это напечатает 0 1 2 3 ..., но это просто зависает. Я полагаю, это потому, что repeat коробления по умолчанию Scheduler, однако, если вы поменяться ролями interval и just-repeat затем он работает, как ожидалось, печать null один раз в секунду:

Observable.just(null).repeat() 
    .sample(Observable.interval(1, TimeUnit.SECONDS)) 
    .subscribe(System.out::println); 

Что здесь происходит?

ответ

3

Если вы не указали планировщик (и ни один оператор не устанавливает его), вся обработка выполняется в том же потоке. just(null).repeat() будет выкачать 100% процессорного ядра, поэтому больше ничего не получится.

В вашем случае interval получает производится на Scedulers.computation() планировщика, и потому, что в начале, и никаких изменений не произойдет, планировщик впоследствии, ваш repeat также работает в том же потоке.

Во втором случае все подписывается на тот же поток, за исключением интервала, который находится на собственном планировщике; остальное зависит от внутренней реализации sample.

Если вы используете конкретный планировщик, он должен работать:

.sample(Observable.just(null).repeat().subscribeOn(Schedulers.computation())) 

Обратите внимание, что если вы просто хотите использовать аннулирует вместо чисел, которые interval производит, гораздо более эффективный способ заключается в использовании map вместо sample:

.map(any -> (Object) null) 
+0

ooooohh, который имеет столько смысла. Я забыл интервал по умолчанию для другого планировщика. d'ах! – flakes

+1

Также похоже, что повтор может принимать планировщик в качестве параметра! 'Повтор (Schedulers.computation())' – flakes