RxJava – Входы клавиатуры с обратным давлением?

Вот забавная проблема RxJava.

Я хочу использовать операторы RxJava backpressure для быстрого поиска введенного ввода, когда набирается каждый символ, подобно тому, как Google делает на своей странице поиска. Я просмотрел документацию Backpressure, и я придумал это (я использую RxJavaFX / RxKotlinFX для использования JavaFX).

val myControl: Node = ... val burstyMulticast = myControl.events(KeyEvent.KEY_TYPED).publish().refCount() val burstyDebounced = burstyMulticast.debounce(200, TimeUnit.MILLISECONDS) val burstyBuffered = burstyMulticast.buffer(burstyDebounced) burstyBuffered .flatMap { it.toObservable().map { it.character }.reduce("") { x,y -> x + y } } .subscribe { println(it) } 

Это отлично работает. Если я наберу «Hello» против элемента управления, он испустит String «Привет» после 200 мс без ввода. Но если я хочу, чтобы это было действительно более отзывчивым, у меня действительно должно быть какое-то скользящее накопление для каждого ввода нажатия клавиши. Тогда мой вывод консоли должен выглядеть так:

 H He Hel Hell Hello высокоэнергетический H He Hel Hell Hello 

Это должны быть все мои выбросы, когда я набираю слово «Привет», а 200 мс определяет, сколько времени должно пройти до того, как накопление сбрасывается. Как мне это сделать?

Вы можете использовать throttleLast вместо денонсации.

throttleLast будет испускать самые последние предметы, испускаемые наблюдаемым в течение периодических интервалов времени

пульт управления throttleLast o / p

 H Hel Hello высокоэнергетический H Hel Hello 

Понял! Я понял, что на самом деле я не хочу buffer() , а скорее switchMap() и scan() внутри него. Я использую многоадресную рассылку для switchMap() как сброса сброса таймера, switchMap() в switchMap() , так и scan() который будет бесконечно конкатенатировать введенные символы до тех пор, пока switchMap() убьет его для сброса.

 val burstyMulticast = events(KeyEvent.KEY_TYPED).publish().refCount().map { it.character } burstyMulticast.throttleLast(1000, TimeUnit.MILLISECONDS).startWith("") .switchMap { burstyMulticast.scan { x,y -> x + y } }.subscribe { println(it) }