#java #android #многопоточность #rxjava
Есть поле для вводе текста, допустим ищем пользователей по имени в БД. Есть метод (упрощенный), который выполняется при каждом наборе символа. public void loadUsers(){ getUsers(mName) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(users -> { //отображение данных }, throwable -> { //обработка ошибки }); } Проблема данного метода в том, что при быстром наборе текста вполне вероятна ситуация, когда ответ на предпоследний запрос пришел позже, чем на последний. Тогда отображаемые данные будут не соответствовать введенному тексту. Вопрос: как обработать запросы в том порядке, в котором выполнялись? Или, может быть, можно игнорировать предыдущие запросы? P.S. С использованием RxJava.
Ответы
Ответ 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 -> { //обработка ошибки }); }Ответ 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 -> { //обработка ошибки }); }
Комментариев нет:
Отправить комментарий