Обработка множественных запросов на RxJava

234
16 августа 2017, 17:20

Есть поле для вводе текста, допустим ищем пользователей по имени в БД.
Есть метод (упрощенный), который выполняется при каждом наборе символа.

    public void loadUsers(){
        getUsers(mName)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(users -> {
             //отображение данных
            }, throwable -> {
             //обработка ошибки
            });
}

Проблема данного метода в том, что при быстром наборе текста вполне вероятна ситуация, когда ответ на предпоследний запрос пришел позже, чем на последний. Тогда отображаемые данные будут не соответствовать введенному тексту.
Вопрос: как обработать запросы в том порядке, в котором выполнялись?
Или, может быть, можно игнорировать предыдущие запросы?
P.S. С использованием RxJava.

Answer 1

Как вариант можно хранить Subscription и её сначала обнулять, а потом новый запрос слать. Типа как-то так (за названия методов не ручаюсь):

Subscription s;
    public void loadUsers() {
        if(s != null && !s.isUnsubscribed()){ 
            s.unsubscribe(); 
        }
        s = getUsers(mName)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(users -> {
                 //отображение данных
                }, throwable -> {
                 //обработка ошибки
                });
    }
Answer 2

Для того чтобы легко обработать эту ситуацию можете использовать библиотеку RxBinding. Она переводит слушатели на Rx что даёт нам легко воспользоваться оператором debounce(). Почитать про оператор можно здесь.

Должно получиться примерно так:

public void loadUsers(){
    RxTextView.afterTextChangeEvents(mNameEditText)
        .debounce(300, TimeUnit.MILLISECONDS)
        .map(TextViewAfterTextChangeEvent::editable)
        .map(Editable::toString)
        .flatMap(name -> getUsers(name))
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(users -> {
            //отображение данных
        }, throwable -> {
           //обработка ошибки
        });
}
READ ALSO
Почему Spring Security не отдает страницу логина?

Почему Spring Security не отдает страницу логина?

Есть страница авторизации которую Spring Security должен отдать но что-то идет не так и я получаю 404Помогите пожалуйста разобраться в чем моя ошибка

278
Не заходит «Hello World!» java, servlet, jsp

Не заходит «Hello World!» java, servlet, jsp

Бьюсь и не могу справиться с простейшим, метод "printText" в классе Class, в сервлете requestsetAttribute на JSP, выводит ошибку 500, гляньте код, что не так? Tomcat8,...

294
Servlet, AJAX, Jsp -> как вернуть страницу JSP

Servlet, AJAX, Jsp -> как вернуть страницу JSP

JS получает данные от API FB и отправляет их на сервлет посредством AJAX

357