web-dev-qa-db-ja.com

破棄時にrxJavaの監視可能なチェーンの実行を停止します

アプリでrxJavaネットワーク呼び出しをデバッグしているときに、disposeのチェーンのサブスクリプションによって返されたclearまたはobservables破棄オブジェクトの場合、最初のobservableのみが破棄され、他のチェーンされたobservablesflatMapによって破棄されないという状況に遭遇しました。

次のデモコードスニペットをご覧ください。

CompositeDisposable testCompositeDisposal = new CompositeDisposable();

private void testLoadData() {
    Disposable disposable = Observable.create(sbr -> {
        for (int i = 0; i < 5; i++) {
            Thread.sleep(3000);
            Log.w("Debug: ", "First: " + i);
            sbr.onNext(true);
        }
        sbr.onComplete();
    }).subscribeOn(Schedulers.io()).flatMap(value -> Observable.create(sbr -> {
        for (int i = 0; i < 5; i++) {
            Thread.sleep(3000);
            Log.w("Debug: ", "Second: " + i);
            sbr.onNext(true);
        }
        sbr.onComplete();
    })).doOnNext(value -> {
        Log.w("Debug: ", "doONNext");
    }).doOnDispose(()-> {
        Log.w("Debug: ", "doOnDispose: observable has been disposed");
    }).subscribe();

    testCompositeDisposal.add(disposable);
}

@Override
public void onStop() {
    super.onStop();
    testCompositeDisposal.clear();
}

出力:

 W/Debug:: First: 0
 W/Debug:: doOnDispose: observable has been disposed // I dispose Observable chain here.
 W/Debug:: First: 1
 W/Debug:: First: 2
 W/Debug:: First: 3
 W/Debug:: First: 4

上記のログ出力でわかるように、指定されたrxJava observableチェーンを破棄すると、最初のobservableのみがアイテムの発行を停止します。

私はそれらが連鎖しているすべての観察可能なものを止めたいと思います。

この問題を解決する慣用的な方法は何ですか?

7
chandil03

2つのこと:

  • flatMapは、アップストリームからアイテムを事前に消費する場合があります(Androidでは最大16)。
  • 2つ目は、ユースケースに当てはまります。onNextを呼び出す前に、オブザーバーが破棄されているかどうかを確認し(.isDisposed()を介して)、その場合は中止する必要があります。

また、secondflatMapは終了します(実際には呼び出されません)。 first1つは続きます。

[〜#〜]編集[〜#〜]

private void testLoadData() { 
    Disposable disposable = Observable.create(sbr -> {
        for (int i = 0; i < 5; i++) {
            if(sbr.isDisposed()) return;  // this will cause subscription to terminate.
            Thread.sleep(3000);
            Log.w("Debug: ", "First: " + i);
            sbr.onNext(true); 
        } 
        sbr.onComplete(); 
    }).subscribeOn(Schedulers.io()).flatMap(value -> Observable.create(sbr -> { 
        for (int i = 0; i < 5; i++) { 
            Thread.sleep(3000); 
            Log.w("Debug: ", "Second: " + i); 
            sbr.onNext(true); 
        } 
        sbr.onComplete(); 
    })).doOnNext(value -> { 
        Log.w("Debug: ", "doONNext"); 
    }).doOnDispose(()-> { 
        Log.w("Debug: ", "doOnDispose: observable has been disposed"); 
    }).subscribe(); 

    testCompositeDisposal.add(disposable); 
} 
7