在RxJava中,链接观察对象时如何传递变量?
我正在使用RxJava链接异步操作,我想向下游传递一些变量:在RxJava中,链接观察对象时如何传递变量?,java,rx-java,reactive-programming,flatmap,Java,Rx Java,Reactive Programming,Flatmap,我正在使用RxJava链接异步操作,我想向下游传递一些变量: Observable .from(modifications) .flatmap( (data1) -> { return op1(data1); }) ... .flatmap( (data2) -> { // How to access data1 here ? return op2(data2); }) 这似乎是一种常见的模式,但我找不到有关它的信息。一种
Observable
.from(modifications)
.flatmap( (data1) -> { return op1(data1); })
...
.flatmap( (data2) -> {
// How to access data1 here ?
return op2(data2);
})
这似乎是一种常见的模式,但我找不到有关它的信息。一种可能是使用函数调用:
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); })
私有静态可观察myFunc(最终对象数据1){
返回op1(数据1)
...
.flatmap((数据2)->{
//我可以在这里访问data1
返回op2(data2);
});
}
可观察
.来自(修改)
.flatmap((数据1)->{return myFunc(数据1);})
但是:如果我错了,请纠正我的错误,但这不像是一种反应式编程方式,另一种可能是将
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/中会让人感觉有点不舒服。。。如果使用Java6表示法,它会变得非常冗长
我想知道是否有更好的解决方案,也许一些RxJava运营商可以提供帮助?我从Couchbase论坛得到的建议是使用嵌套的可观察对象:
Observable
.from(modifications)
.flatmap( (data1) -> {
return op1(data1)
...
.flatmap( (data2) -> {
// I can access data1 here
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);
})
希望有帮助flatmap可以使用第二个参数:
Observable.just("foo")
.flatMap(foo -> Observable.range(1, 5), Pair::of)
.subscribe(pair -> System.out.println("Result: " + pair.getFirst() + " Foo: " + pair.getSecond()));
来源:您可以使用“全局”变量来实现以下目标:
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);
})
我知道这是一个老问题,但是使用RxJava2和lambda, 您可以使用以下内容:
Observable
.from(modifications)
.flatMap((Function<Data1, ObservableSource<Data2>>) data1 -> {
//Get data 2 obeservable
return Observable.just(new Data2())
}
}, Pair::of)
可观察
.来自(修改)
.flatMap((函数)数据1->{
//获取可维护的数据2
返回Observable.just(新数据2())
}
},成对的)
在下一个流(flatmap/map)中,您的输出对将是(data1,data2)实际上我们有一个库,它简化了调用链 添加为渐变依赖项:
implementation 'io.reactivex.rxjava2:rxjava:2.2.1'
implementation 'com.github.pakoito.Komprehensions:komprehensions-rx2:1.3.2'
用法(Kotlin):
这是我发现自己经常做的事情,到目前为止效果很好。嗯,这与我的“在流之外存储数据”没有太大区别。我不认为这样做有什么错,但每当我觉得我需要接触结对类时,我也觉得我做错了什么。我使用它的次数,然后在我对我的领域有了更好的了解后重新计算。这就是我想到的解决方案,尽管它会创建大量垃圾制造
成对
实例,只是为了将数据1
放在obj
旁边。我想知道一个组合是否有效。这与您的第一个选项有很大不同吗?@是的,我想它的功能类似于使用嵌套调用。对于复杂的处理,这可能毕竟不是一个坏的选择。不幸的是,这可能不是线程安全的(取决于您的代码RxJava将在多个线程上运行计算)。我很困惑,如果RxJava为数据创建多个线程,为什么私有的非静态变量会是线程“不安全的”,CommonData实例将在线程之间共享,即使它不是静态的。(这应该可以通过一些显示当前线程和CommonData值的日志进行测试)我需要找到另一个解决方案,因为如果必须执行以下操作:if(boolean)return observer 1 else return observer 2;您必须在这两个平面上绘制平面图,这将是。。badhow to import Pair?@DynoCris您可以编写自己的或从一些libs(仅谷歌java+Pair)简单而干净地导入它。这应该是可以接受的答案。这是错误的建议,不要将数据存储在流之外,使用SwitchMap或类似的方法传递数据。这是反模式。
val observable = doFlatMap(
{ Observable.from(modifications) },
{ data1 -> op1(data1) },
{ data1, data2 -> op2(data2) },
{ data1, data2, data3 -> op3(data1, data2, data3) }
)