2015-11-24 49 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() 

当我通过3次按下“A”按钮,在Android设备上执行该代码,我得到以下结果:

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

并延迟观察到的发射目的何在?我想这可能不是你正在寻找的运营商。也许控制排放之间的时间反弹会更好? –

+0

我已经介绍它来模拟将文本映射到结果列表时产生的查询延迟。通过这样做,我可以在android和jvm中重现问题。 Irl,延迟呼叫不会在那里,但同样的问题发生。 – nhaarman

+0

代码(修复编译错误之后)在桌面上适用于我。您可以在observeOn和delay之间添加doOnNext(),并查看事情消失的地方。 (如果函数参数名也包含在封闭范围内,也可能会将函数参数名绑定到错误的变量上。) – akarnokd

回答

0

TextViewTextWatcherseems to reuse新的更新(可变的)CharSequence,改变所有延迟项目以及。

该问题与RxJava无关。真正的问题是TextWatcher.onTextChanged是用相同的可变CharSequence实例调用的,所以在EditText中输入一个新字符会使所有延迟的值无效。

因此,第一映射CharSequenceString解决了这个问题:

RxTextView.textChangeEvents(mTextView) 
    .map(new Func1<CharSequence, String>() { 
    @Override 
    public void call(CharSequence charSequence) { 
     return String.valueOf(charSequence); 
    } 
    }) 
    ...