[英]In RxJava, how to pass a variable along when chaining observables?
我正在使用 RxJava 鏈接異步操作,我想向下游傳遞一些變量:
Observable
.from(modifications)
.flatmap( (data1) -> { return op1(data1); })
...
.flatmap( (data2) -> {
// How to access data1 here ?
return op2(data2);
})
這似乎是一種常見的模式,但我找不到有關它的信息。
我從 Couchbase 論壇得到的建議是使用嵌套的 observables:
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 可以采用第二個參數:
Observable.just("foo")
.flatMap(foo -> Observable.range(1, 5), Pair::of)
.subscribe(pair -> System.out.println("Result: " + pair.getFirst() + " Foo: " + pair.getSecond()));
來源: https ://medium.com/rxjava-tidbits/rxjava-tidbits-1-use-flatmap-and-retain-original-source-value-4ec6a2de52d4
一種可能性是使用函數調用:
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); })
但是:如果我錯了,請糾正我,但感覺不像是反應式編程方式
實際上我們有庫,可以簡化調用鏈。
https://github.com/pakoito/Komprehensions
添加為 Gradle 依賴項:
implementation 'io.reactivex.rxjava2:rxjava:2.2.1'
implementation 'com.github.pakoito.Komprehensions:komprehensions-rx2:1.3.2'
用法(科特林):
val observable = doFlatMap(
{ Observable.from(modifications) },
{ data1 -> op1(data1) },
{ data1, data2 -> op2(data2) },
{ data1, data2, data3 -> op3(data1, data2, data3) }
)
我知道這是一個老問題,但是使用 RxJava2 和 lambda,你可以使用類似的東西:
Observable
.from(modifications)
.flatMap((Function<Data1, ObservableSource<Data2>>) data1 -> {
//Get data 2 obeservable
return Observable.just(new Data2())
}
}, Pair::of)
在下一個流程(平面圖/地圖)上,您的輸出對將是 (data1, 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);
})
希望能幫助到你
你可以使用 resultSelector BiFunction<? super T, ? super U, ? extends R> resultSelector
BiFunction<? super T, ? super U, ? extends R> resultSelector
BiFunction<? super T, ? super U, ? extends R> resultSelector
flatmap 中的第二個參數,可以選擇返回哪個結果。
您可以使用“全局”變量來實現這一點:
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);
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.