我正在使用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);
})
这似乎是一种常见的模式,但是我找不到有关它的信息。
Answers:
我从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操作员可以提供帮助?
Pair
实例,只是要保留在data1
旁边obj
。我想知道acombine
是否可行。
flatmap可能需要第二个arg:
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) }
)
此线程上的解决方案有效,但是对于复杂的链,它使代码难以阅读,我不得不传递多个值,而我所做的就是创建一个带有所有参数的私有类,我发现这种方式的代码更具可读性,
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);
})