RxJava .toblocking.tosingle()根本没有返回

时间:2016-09-26 20:34:07

标签: parallel-processing rx-java observable

我正在尝试对两个不同的REST服务进行并行调用,这些服务返回不同类型的响应。所以我使用了observable.zip(...).toBlocking().single(),但它根本不会返回。

这是我正在做的......

  1. 尝试使用rx zip
  2. 对不同的服务进行并行调用

    我想打电话给的服务 订单信息 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项服务并行呼叫。

1 个答案:

答案 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))个别可观察数据。

例如,要同时压缩ab以及c

Scheduler scheduler = Schedulers.io();
a
 .zipWith(b.subscribeOn(scheduler))
 .zipWith(c.subscribeOn(scheduler))
 .subscribe(subscriber);