2015-11-24 3 views
0

Я пытаюсь сделать некоторые поиска, когда пользователь вводит текст в TextView:RxJava ObserveOn неправильно передает элементы?

RxTextView.textChangeEvents(mTextView) 
    .doOnNext(new Action1<CharSequence>() { 
    @Override 
    public void call(CharSequence charSequence) { 
     System.out.println("OnNext: " + charSequence); 
    } 
    }) 
    .observeOn(mSchedulerProvider.computation()) 
    .delay(1, SECONDS, mSchedulerProvider.computation()) 
    .map(new Func1<CharSequence, Object>() { 
    @Override 
    public void call(CharSequence charSequence) { 
     System.out.println("Map: " + charSequence); 
    } 
    }) 
    .subscribe() 

Когда я выполняю этот код на Android устройства в 3 раза нажав на кнопку «а», я получаю следующий результат :

onNext: a 
onNext: aa 
onNext: aaa 
Map: aaa 
Map: aaa 
Map: aaa 

я ожидал, моя последовательность CharSequence быть такой же, как и в onNext вызова.

Когда я запускаю следующий тест на JVM:

mQuerySubject.onNext("a"); 
    mSchedulerProvider.computation().advanceTimeBy(150, TimeUnit.MILLISECONDS); 
    mQuerySubject.onNext("aa"); 
    mSchedulerProvider.computation().advanceTimeBy(150, TimeUnit.MILLISECONDS); 
    mQuerySubject.onNext("aaa"); 

    mSchedulerProvider.computation().advanceTimeBy(2, TimeUnit.SECONDS); 
    mSchedulerProvider.computation().triggerActions(); 

..Это делает печать из ожидаемого результата:

onNext: a 
onNext: aa 
onNext: aaa 
Map: a 
Map: aa 
Map: aaa 

Почему это происходит?

+0

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

+0

Я представил его для моделирования задержки запроса, которая возникла бы путем сопоставления текста со списком результатов. Делая это таким образом, я могу воспроизвести проблему как в android, так и в jvm. Irl, вызова задержки не будет, но та же проблема возникает. – nhaarman

+0

Код (после исправления ошибки компиляции) работает для меня на рабочем столе. Вы можете добавить doOnNext() между наблюдением и задержкой и посмотреть, где вещи исчезнут. (Также возможно, что имя параметра функции связывается с неправильной переменной, если оно есть и в охватывающей области.) – akarnokd

ответ

0

TextView «s TextWatcherseems to reuse (изменяемые) CharSequence новых обновлений, изменение всех задержанных предметов, а также.

Вопрос не имеет ничего общего с RxJava. Реальная проблема заключается в том, что TextWatcher.onTextChanged вызывается с тем же измененным экземпляром CharSequence, поэтому ввод нового символа в EditText сделает все замедленные значения недопустимыми.

Таким образом, первое КАРТОГРАФИРОВАНИЯ CharSequence к String решает эту проблему:

RxTextView.textChangeEvents(mTextView) 
    .map(new Func1<CharSequence, String>() { 
    @Override 
    public void call(CharSequence charSequence) { 
     return String.valueOf(charSequence); 
    } 
    }) 
    ... 
Смежные вопросы