这是我的代码
final ApiInterface apiInterface=restAdapter.create(ApiInterface.class);
apiInterface.submitDataToAnalyze("dataToAnalyze","852741963",1,"123","lalala","2015-11-20")
.flatMap(new Func1<BasicResponse, Observable<?>>() {
@Override
public Observable<?> call(BasicResponse basicResponse) {
if (basicResponse.getResult() == 1){
return apiInterface.getSuggestion("dataToAnalyze","852741963",1,"123","lalala","2015-11-20");
}else{
return null; //error
}
}
}).flatMap(new Func1<Observable<?>, Integer>() {
@Override
public Integer call(Observable<?> input) {
if (input == null){
//update a table
return 0;
}else{
//update another table using data retrieved from apiInterface.getSuggestion
return 1;
}
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
我应该怎么做,以便在通话完成时,在
返回apiInterface.getSuggestion()
或
返回Observable.just(null)
将调用两个不同的功能(每种情况一个)?当然,该函数需要处理从调用返回的数据。
顺便说一句,第二个flatMap返回此错误:
'flatMap(rx.functions.Func1<? super java.lang.Object,? extends rx.Observable<?>>)' in 'rx.Observable' cannot be applied to '(anonymous rx.functions.Func1<rx.Observable<?>,java.lang.Integer>)'
如果有帮助,这里是我的submitDataToAnalyze和getSuggestion的界面
@POST("/request.php")
Observable<BasicResponse> submitDataToAnalyze(@Query("action") String action, @Query("auth") String auth, @Query("ver") int ver, @Query("uuid") String uuid, @Query("dataToAnalyze") String dataToAnalyze,
@Query("requestForDate") String requestForDate);
@POST("/request.php")
Observable<BasicResponse> getSuggestion(@Query("action") String action, @Query("auth") String auth, @Query("ver") int ver, @Query("uuid") String uuid, @Query("dataToAnalyze") String dataToAnalyze,
@Query("requestForDate") String requestForDate);
答案 0 :(得分:3)
关于map
和flatMap
之间的区别 - 对于所有情况,确实没有简单的答案。总的来说,我这样做是这样的:
我使用map
进行所有简单的一对一转换:链中的每个X都应转换为一个Y.
一些例子:
String
转换为另一个String
Pair<Integer, Integer>
转换为Integer
List<Double>
转换为Double
正如您所看到的,X和Y可以是任何类型(事实上,其中一个或两个可能是复杂的数据类型,如Collection
) - 但是,对于每个输入实体,您仍然可以获得输出实体。 我使用flatMap
表示至少满足下列条件之一的情况:
如果这三个条件听起来很熟悉,那是因为Erik Meijer在他的演讲中列出了这些条件:https://www.youtube.com/watch?v=sTSQlYX5DU0
关于更新代码中的编译错误 - 正确的类型声明应如下所示:
apiInterface.submitDataToAnalyze("dataToAnalyze","852741963",1,"123","lalala","2015-11-20")
.flatMap(new Func1<BasicResponse, Observable<BasicResponse>>() {
@Override
public Observable<BasicResponse> call(BasicResponse basicResponse) {
if (basicResponse.getResult() == 1){
return apiInterface.getSuggestion("dataToAnalyze","852741963",1,"123","lalala","2015-11-20");
} else {
return Observable.just(null);
}
}
})
.flatMap(new Func1<BasicResponse, Observable<Integer>>() {
@Override
public Observable<Integer> call(BasicResponse input) {
if (input == null){
//update a table
return Observable.just(0);
} else {
//update another table using data retrieved from apiInterface.getSuggestion
return Observable.just(1);
}
}
由于getSuggestion
返回的Observable<BasicResponse>
必须是第一个Func1
的返回类型 - 即使返回的实际值必须为null
。
我认为你的误解在于后面的内容,所以让我们来看看。然后RxJava没有通过链中的Observable<BasicResponse>
- 因为您使用flatMap
,它将在内部订阅您已创建的Observable<BasicResponse>
,然后将该Observable发出的每个项目并传递 。这也是下一个Func1
必须是Func1<BasicResponse, Observable<Integer>>
而不是Func1<Observable<BasicResponse>, Observable<Integer>>
的原因。在链中等待的任何函数的输入类型必须是BasicReponse
,因为这是&#34; unpacked&#34;的类型。来自Observable<BasicResponse>
的商品。我希望这很清楚,如果有点冗长。
要回到最后一部分的map
与flatMap
,您可以使用其中任何一个。如果您正确使用它,flatMap
始终有效。但是map
通常可以更短(并且可能更高效,因为它不会创建更多的内部Observable)。一般情况下,如果您有一个flatMap
并且在每个分支中只返回Observable.just()
,您也可以使用简单的地图。所以你可能会把你的代码重写为:
.map(new Func1<BasicResponse, Integer>() {
@Override
public Integer call(BasicResponse input) {
if (input == null){
//update a table
return 0;
} else {
//update another table using data retrieved from apiInterface.getSuggestion
return 1;
}
}
答案 1 :(得分:1)
flatMap
应该返回一个可观察对象,因此return null
应该是return Observable.just(null)
而不是null
。当您将其他运算符链接到flatmap
时,直接返回$(document).on("click", selectorString, function(event) {
// do stuff
});
将导致NPE。
之后,您可以链接下一个操作。使用什么操作符实际上取决于您希望该功能执行的操作。
答案 2 :(得分:1)
两个建议:
使用filter
:
apiInterface.submitDataToAnalyze(...)
.filter(br -> br.getResult() == 1)
.flatMap(new Func1<BasicResponse, Observable<?>>() {
@Override
public Observable<?> call(BasicResponse basicResponse) {
return apiInterface.getSuggestion(...);
}
})
...
或在Observable.empty()
中返回flatMap
:
if (basicResponse.getResult() == 1){
return apiInterface.getSuggestion(...);
}else{
return Observable.empty();
}