Поток для фильтрации до тех пор, пока не будет испущен другой поток, но повторите передачу отфильтрованных излучений после того, как 2-й поток испустит

У меня есть поток Foo. Для испускания Foo требуется, чтобы Android View был выложен (ширина и высота > 0). Я использую RxBinding для этого, т.е.

fooOservable()
   .subscribe(foo -> {});

RxView.preDraws(mPager, () -> true)
                    .take(1);

Когда этот наблюдаемый исходит (или завершается, из-за взятия), выкладывается представление.

Что мне нужно, так это чтобы fooObservable() ждал, пока RxView выдаст, т.е. представление будет выложено. Я не могу просто fooObservable.filter(width && height > 0), потому что это отбрасывает эмиссии. Что мне нужно, так это кэшировать последний выброс foo (если представление не выложено) и повторно отправить после первого RxView.preDraws., если он выложен, он должен пройти нормально


person urSus    schedule 31.08.2017    source источник


Ответы (2)


Вы можете использовать delay или delaySubsription. Существуют формы, которые откладывают выбросы или подписку до тех пор, пока другой наблюдаемый объект не излучает что-то. В первом случае у вас будет только задержка эмиссии, во втором случае будет отложена вся подписка.

person MightySeal    schedule 31.08.2017

Я написал образец, используя задержку, чтобы дождаться другого наблюдаемого, прежде чем выдавать ваши данные.

class SimpleTest {
  val testScheduler = TestScheduler()

  @Test
  fun test() {
    fooObservable()
        .doOnNext { logger("Next", it.toString()) }
        .delay { Observable.timer(5, TimeUnit.SECONDS, testScheduler) }
        .subscribe { logger("Delayed", it.toString()) }

    testScheduler.advanceTimeBy(10, TimeUnit.SECONDS)
  }

  fun fooObservable(): Observable<Int> {
    return Observable.just(1, 2, 3, 4)
  }

  fun logger(tag: String, message: String): Unit {
    val formattedDate = Date(testScheduler.now()).format()
    System.out.println("$tag @ $formattedDate: $message")
  }

  fun Date.format(): String {
    return SimpleDateFormat("HH:mm:ss.SSS", Locale.US).format(this)
  }
}

Я использовал 5-секундный таймер для имитации вашего вторичного наблюдаемого.

Этот код печатает этот вывод:

Next @ 21:00:00.000: 1
Next @ 21:00:00.000: 2
Next @ 21:00:00.000: 3
Next @ 21:00:00.000: 4
Delayed @ 21:00:05.000: 1
Delayed @ 21:00:05.000: 2
Delayed @ 21:00:05.000: 3
Delayed @ 21:00:05.000: 4
person Rodrigo Henriques    schedule 31.08.2017