我找不到一种方法来组合或链接一个observable列表,它的响应是创建另一个Observable的其他调用的先决条件。
我正在使用observable进行改造。
我的服务:
String url = "/geocode/json?sensor=false";
@GET(url)
Observable<GeocodeResult> getReverse(@Query("key") String gMapsKey,
@Query("latlng") LatLng origin);
另一项服务需要GeocodeResult
@POST("/api/orders")
Observable<Order> createOrder(@Body GeocodeResult newOrder);
我正在尝试:
//先决条件1 Observable geocodeObservable = Address.get(...);
//获取地理编码后调用createOrder? 返回Observable.combineLatest(geocodeObservable,geocode - &gt; createOrder(geocode));
但它不起作用因为combineLatest需要一个对象,而不是一个可观察对象,但我需要返回observable。
使用JoinObservable:
Pattern5<Geocode> pattern = JoinObservable.from(geocodeObservable)
Plan0<Observable<Order>> plan = pattern.then(Order::create);
return JoinObservable.when(plan).toObservable().toBlocking().single();
但它会抛出NoSuchElementException异常。为什么?
我做toBlocking().single()
因为我需要Observable而不是Observable<Observable<Order>>
:(。
或者我该怎么办?
答案 0 :(得分:6)
您可以尝试使用flatMap,它可以将第二个observable作为参数。
该函数获取第一个observable发出的项,并为每个项创建一个observable,然后将这些observable发出的项展平为一个observable。这听起来很复杂,但幸运的是,你的Retrofit函数只会发出一个单独的项目,所以只有一个observable得到了平坦的&#34;成为一个可观察的。
您可以像这样使用flatMap
:
restApi.getReverse(gMapsKey, origin)
.flatMap(geocodeResult -> createOrder(geocodeResult))
.subscribe(order -> doSomething(order));
combineLatest
并不能满足您的需求,因为它可以同时执行两个REST调用,而不是一个接一个地执行,因此您无法使用第一个的响应作为第二个参数。我无法评论为什么JoinObservable
引发异常,因为它不是任何公共API的一部分。 toBlocking()
也不应该用于测试以外的任何事情。
答案 1 :(得分:2)
我最终创建了一个新的Object并使用Observable.combineLatest
组合创建新Observable的所有先决条件,然后使用flatMap从该observable创建新的Observable。
Observable<NewOrderWrapper> newOrderObservable = Observable.combineLatest(prerequisites, (param1, param2,...) -> {return new NewOrderWrapper(param1, param2,...)});
然后
Observable<Order> finalOrderObservable = newOrderObservable.flatMap(newOrderWrapper -> create(newOrderWrapper))
在此处查看帖子MakinGIANST/RXJava post。
感谢@LukaCiko