我正在尝试对两个不同的REST服务进行并行调用,这些服务返回不同类型的响应。所以我使用了observable.zip(...).toBlocking().single()
,但它根本不会返回。
这是我正在做的......
我想打电话给的服务 订单信息 2. billInfo
@Service
public class ParallelServiceCallImpl {
...//var declaration ...
Observable<OrderInfoResponse> getOrderInfoRsp(ServiceRequest serviceRequest) {
return Observable.create((rx.Subscriber <? super OrderInfoResponse> s) -> {
OrderInfoResponse ordrInfo = orderComponent.getOrderDetails(serviceRequest); // this component calls to end service
});
}
Observable<BillInfoResponse> getBillInfoRsp(ServiceRequest serviceRequest) {
return Observable.create((rx.Subscriber <? super BillInfoResponse> s) -> {
BillInfoResponse billInfo = billInfoComponent.getBillingDetails(serviceRequest); // this component calls to end service
});
}
public ServiceEndResponse getServiceBillFinance(ServiceRequest serviceRequest) {
Observable<OrderInfoResponse> orderObservable = getOrderInfoRsp(serviceRequest);
Observable<BillInfoResponse> billObservable = getBillInfoRsp(serviceRequest);
Observable<ServiceEndResponse> responseObservable = Observable.zip(
orderObservable,
billObservable,
(ordrInfo, billInfo) -> {
ServiceEndResponse serviceEndResponse = serviceMapper.endResponseMapper(ordrInfo, billInfo);
return serviceEndResponse;
}
);
ServiceEndResponse serviceResponse = responseObservable.toBlocking().single(); // Not getting response
return serviceResponse;
}
}
请告诉我这里缺少的内容,为什么不返回serviceResponse
我想再添加一个......
我在getProducts
中使用了ProductComponent
方法,为所有ProductInfo
并行调用productIds
服务
public List<ProductsInfo> getProducts(ServiceRequest serviceRequest, List<String> productIds) {
List<ProductsInfo> lstProductInfo = new ArrayList<ProductsInfo>();
List<Observable<ProductsInfo>> lstPrd = new ArrayList<Observable<ProductsInfo>>(productIds.size());
for (String prdID : productIds) {
Observable<ProductsInfo> prd = getProductObservable(serviceRequest, prdID); //Observable
lstPrd.add(prd);
}
Iterable<Observable<ProductsInfo>> iterable = (Iterable<Observable<ProductsInfo>>)lstPrd;
List<ProductsInfo> listofProd = Observable.zip(iterable, new FuncN<List<ProductsInfo>>(){
public List<ProductsInfo> call(Object...args) {
for (Object arg : args) { lstProductInfo.add((ProductsInfo)arg);}
return lstProductInfo;
}
}).toBlocking().single();
return lstProductInfo;
}
//Create and Return Observable
private Observable<ProductsInfo> getProductObservable(ServiceRequest serviceRequest, String productId ) {
return Observable.create((rx.Subscriber<? super ProductsInfo> s) -> {
ProductsInfo prdct = getProduct(serviceRequest, productId);
s.onNext(prdct);
s.onCompleted();
}).subscribeOn(Schedulers.io());
}
//Call End Service
private ProductsInfo getProduct(ServiceRequest serviceRequest, String productId) {
serviceRequest.setProductID(productId);
//service invocation
svcResponse = getProductEndPoint.getProducts(serviceRequest);//**********/
ProductsInfo product = serviceMapper.productMapper(svcResponse);
return product;
}
我希望与ProductComponent.getProducts(ServiceRequest serviceRequest, List<String> productIds)
以及上述2项服务并行呼叫。
答案 0 :(得分:1)
不要使用create(OnSubscribe)
,背压和取消订阅可能很难兑现。但是,当您使用create
时,您没有向订阅者s
发送任何项目,因此单个项目永远不会到达。
而不是create
使用fromCallable
:
Observable<BillInfoResponse> getBillInfoRsp(ServiceRequest serviceRequest) {
return Observable.fromCallable(() ->
billInfoComponent.getBillingDetails(serviceRequest));
}
然后继续执行zip
。如果observable代表网络呼叫,您可能还需要将.timeout
添加到网络呼叫的observable中,以便在呼叫挂起时提前失败。
在运行网络调用时,Observables并行使用.subscribeOn(Schedulers.io())
或.subscribeOn(Schedulers.from(ExecutorService))
个别可观察数据。
例如,要同时压缩a
和b
以及c
:
Scheduler scheduler = Schedulers.io();
a
.zipWith(b.subscribeOn(scheduler))
.zipWith(c.subscribeOn(scheduler))
.subscribe(subscriber);