2015-11-24 47 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); 
    } 
    }) 
    ...