java 在 RxJava 中,如何在链接 observable 时传递变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28176072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In RxJava, how to pass a variable along when chaining observables?
提问by Julian Go
I am chaining async operations using RxJava, and I'd like to pass some variable downstream:
我正在使用 RxJava 链接异步操作,并且我想向下游传递一些变量:
Observable
.from(modifications)
.flatmap( (data1) -> { return op1(data1); })
...
.flatmap( (data2) -> {
// How to access data1 here ?
return op2(data2);
})
It seems like a common pattern but I couldn't find information about it.
这似乎是一种常见的模式,但我找不到有关它的信息。
采纳答案by Julian Go
The advice I got from the Couchbase forum is to use nested observables:
我从 Couchbase 论坛得到的建议是使用嵌套的 observables:
Observable
.from(modifications)
.flatmap( (data1) -> {
return op1(data1)
...
.flatmap( (data2) -> {
// I can access data1 here
return op2(data2);
})
});
EDIT: I'll mark this as the accepted answer as it seems to be the most recommended. If your processing is too complex to nest everything you can also check the solution with function calls.
编辑:我会将其标记为已接受的答案,因为它似乎是最推荐的。如果您的处理太复杂而无法嵌套所有内容,您还可以通过函数调用检查解决方案。
回答by Julian Go
Another possibility is to map the result of op1
to a org.apache.commons.lang3.tuple.Pair
that contains the variable and pass that along:
另一种可能性是将 的结果映射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());
})
It works but it feels a bit uncomfortable to have variables hidden inside a Pair/Triple/... and it gets very verbose if you use the Java 6 notation.
它可以工作,但是将变量隐藏在 Pair/Triple/... 中感觉有点不舒服,如果您使用 Java 6 表示法,它会变得非常冗长。
I wonder if there is a better solution, maybe some RxJava operator could help?
我想知道是否有更好的解决方案,也许一些 RxJava 操作员可以提供帮助?
回答by Sisyphus
flatmap can take a second arg:
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
回答by Julian Go
One possibility would be to use a function call:
一种可能性是使用函数调用:
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); })
BUT: correct me if I'm wrong but it doesn't feel like the reactive-programming way of doing it
但是:如果我错了,请纠正我,但这感觉不像是反应式编程的方式
回答by Andrew
Actually we have library, that simplify call chains.
实际上我们有库,可以简化调用链。
https://github.com/pakoito/Komprehensions
https://github.com/pakoito/Komprehensions
Adding as Gradle dependency:
添加为 Gradle 依赖项:
implementation 'io.reactivex.rxjava2:rxjava:2.2.1'
implementation 'com.github.pakoito.Komprehensions:komprehensions-rx2:1.3.2'
Usage (Kotlin):
用法(科特林):
val observable = doFlatMap(
{ Observable.from(modifications) },
{ data1 -> op1(data1) },
{ data1, data2 -> op2(data2) },
{ data1, data2, data3 -> op3(data1, data2, data3) }
)
回答by josesuero
solution on this thread works, but for complex chains it makes code difficult to read, I had to pass multiple values and what i did was create a private class with all parameters, I find code to be more readable this way,
这个线程上的解决方案有效,但对于复杂的链,它使代码难以阅读,我不得不传递多个值,我所做的是创建一个包含所有参数的私有类,我发现这样的代码更具可读性,
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);
})
hope it helps
希望能帮助到你
回答by Ndivhuwo
I know this is an old question, but using RxJava2 & lambda, You can use something like:
我知道这是一个老问题,但是使用 RxJava2 和 lambda,您可以使用以下内容:
Observable
.from(modifications)
.flatMap((Function<Data1, ObservableSource<Data2>>) data1 -> {
//Get data 2 obeservable
return Observable.just(new Data2())
}
}, Pair::of)
On the next flow (flatmap/map) your output pair will be (data1, data2)
在下一个流 (flatmap/map) 中,您的输出对将是 (data1, data2)
回答by happyyangyuan
You can use "global" variable to achive this:
您可以使用“全局”变量来实现这一点:
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);
})