RxJavaを使用して非同期操作をチェーンしているため、下流にいくつかの変数を渡したいと思います。
Observable
.from(modifications)
.flatmap( (data1) -> { return op1(data1); })
...
.flatmap( (data2) -> {
// How to access data1 here ?
return op2(data2);
})
よくあるパターンのようですが、それに関する情報が見つかりませんでした。
Couchbaseフォーラムから得たアドバイスは、ネストされたオブザーバブルを使用することです。
Observable
.from(modifications)
.flatmap( (data1) -> {
return op1(data1)
...
.flatmap( (data2) -> {
// I can access data1 here
return op2(data2);
})
});
編集:これが最も推奨されると思われるため、これを受け入れられた答えとしてマークします。処理が複雑すぎてすべてをネストできない場合は、関数呼び出しでソリューションを確認することもできます。
別の可能性は、op1
の結果を変数を含むorg.Apache.commons.lang3.Tuple.Pair
にマッピングし、それを渡すことです:
Observable
.from(modifications)
.flatmap( (data1) -> {
return op1(data1).map( obj -> { return Pair.of(data1,obj); });
})
...
.flatmap( (dataPair) -> {
// data1 is dataPair.getLeft()
return op2(dataPair.getRight());
})
動作しますが、Pair/Triple/...の内部に変数を隠すのは少し不快に感じます。また、Java 6表記を使用すると非常に冗長になります。
より良い解決策があるのだろうか、おそらくRxJavaオペレータが助けてくれるだろうか?
flatmapは2番目の引数を取ることができます:
Observable.just("foo")
.flatMap(foo -> Observable.range(1, 5), Pair::of)
.subscribe(pair -> System.out.println("Result: " + pair.getFirst() + " Foo: " + pair.getSecond()));
1つの可能性は、関数呼び出しを使用することです。
private static Observable<T> myFunc(final Object data1) {
return op1(data1)
...
.flatmap( (data2) -> {
// I can access data1 here
return op2(data2);
});
}
Observable
.from(modifications)
.flatmap( (data1) -> { return myFunc(data1); })
しかし、私が間違っている場合は修正しますが、それを行うリアクティブプログラミング方法のようには感じません
これを実現するために「グローバル」変数を使用できます。
Object[] data1Wrapper = new Object[]{null};
Object[] data2Wrapper = new Object[]{null};
Observable
.from(modifications)
.flatmap(data1 -> {
data1Wrapper[0] = data1;
return op1(data1)
})
...
.flatmap(data2 -> {
// I can access data1 here use data1Wrapper[0]
Object data1 = data1Wrapper[0];
data2Wrapper[0] = data2;
return op2(data2);
})
このスレッドのソリューションは機能しますが、複雑なチェーンの場合、コードを読みにくくするため、複数の値を渡す必要があり、すべてのパラメーターを持つプライベートクラスを作成しました。
private class CommonData{
private string data1;
private string data2;
*getters and setters*
}
...
final CommonData data = new CommonData();
Observable
.from(modifications)
.flatmap( (data1) -> {
data.setData1(data1);
return op1(data1);
})
...
.flatmap( (data2) -> {
data2 = data.getData1() + "data 2... ";
data.setData2(data2);
return op2(data2);
})
それが役に立てば幸い
これは古い質問ですが、RxJava2とラムダを使用すると、次のようなものを使用できます。
Observable
.from(modifications)
.flatMap((Function<Data1, ObservableSource<Data2>>) data1 -> {
//Get data 2 obeservable
return Observable.just(new Data2())
}
}, Pair::of)
次のフロー(flatmap/map)では、出力ペアは(data1、data2)になります