アプリでrxJavaネットワーク呼び出しをデバッグしているときに、dispose
のチェーンのサブスクリプションによって返されたclear
またはobservables
破棄オブジェクトの場合、最初のobservable
のみが破棄され、他のチェーンされたobservables
はflatMap
によって破棄されないという状況に遭遇しました。
次のデモコードスニペットをご覧ください。
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のみがアイテムの発行を停止します。
私はそれらが連鎖しているすべての観察可能なものを止めたいと思います。
この問題を解決する慣用的な方法は何ですか?
2つのこと:
flatMap
は、アップストリームからアイテムを事前に消費する場合があります(Androidでは最大16)。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);
}