我正在使用 RxJava 链接异步操作,我想向下游传递一些变量:
Observable
.from(modifications)
.flatmap( (data1) -> { return op1(data1); })
...
.flatmap( (data2) -> {
// How to access data1 here ?
return op2(data2);
})
这似乎是一种常见的模式,但我找不到有关它的信息。
我正在使用 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
包含变量的 a 并将其传递:
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()));
一种可能性是使用函数调用:
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);
})
希望能帮助到你
您可以使用“全局”变量来实现这一点:
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);
})