Вот забавная проблема 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) }