Java 如何等待async Observable完成

Java 如何等待async Observable完成,java,rx-java,Java,Rx Java,我正在尝试使用rxjava构建一个示例。该示例应协调一个ReactiveWareService和一个ReactiveReviewService,以重新运行WareAndReview组合 ReactiveWareService public Observable<Ware> findWares() { return Observable.from(wareService.findWares()); } ReactiveReviewService

我正在尝试使用rxjava构建一个示例。该示例应协调一个ReactiveWareService和一个ReactiveReviewService,以重新运行WareAndReview组合

ReactiveWareService
        public Observable<Ware> findWares() {
        return Observable.from(wareService.findWares());
    }

ReactiveReviewService: reviewService.findReviewsByItem does a ThreadSleep to simulate a latency!

public Observable<Review> findReviewsByItem(final String item) {
return Observable.create((Observable.OnSubscribe<Review>) observer -> executor.execute(() -> {
    try {
        List<Review> reviews = reviewService.findReviewsByItem(item);
        reviews.forEach(observer::onNext);
        observer.onCompleted();
    } catch (Exception e) {
        observer.onError(e);
    }
}));
}

public List<WareAndReview> findWaresWithReviews() throws RuntimeException {
final List<WareAndReview> wareAndReviews = new ArrayList<>();

wareService.findWares()
    .map(WareAndReview::new)
.subscribe(wr -> {
        wareAndReviews.add(wr);
        //Async!!!!
        reviewService.findReviewsByItem(wr.getWare().getItem())
            .subscribe(wr::addReview,
                throwable -> System.out.println("Error while trying to find reviews for " + wr)
            );
    }
);

//TODO: There should be a better way to wait for async reviewService.findReviewsByItem completion!
try {
    Thread.sleep(3000);
} catch (InterruptedException e) {}

return wareAndReviews;
}
ReactiveWareService
公共可观测findWares(){
从(wareService.findWares())返回可观测值;
}
ReactiveReviewService:reviewService.findReviewsByItem执行ThreadSleep以模拟延迟!
公共可观测findReviewsByItem(最终字符串项){
返回Observable.create((Observable.OnSubscribe)observer->executor.execute(()->{
试一试{
列表审查=reviewService.findReviewsByItem(项目);
评论。forEach(观察员::onNext);
observer.onCompleted();
}捕获(例外e){
观察员:onError(e);
}
}));
}
public List findWaresWithReviews()引发运行时异常{
最终列表wareAndReviews=newarraylist();
wareService.findWares()
.map(WareAndReview::新建)
.订阅(wr->{
wareAndReviews.add(wr);
//异步!!!!
reviewService.findReviewsByItem(wr.getWare().getItem())
.订阅(wr::addReview,
throwable->System.out.println(“试图查找“+wr”的评论时出错)
);
}
);
//TODO:应该有更好的方法等待async reviewService.findReviewsByItem完成!
试一试{
睡眠(3000);
}捕获(中断异常e){}
返回wareAndReviews;
}

鉴于我不想返回一个可观察的对象,我怎么能等待async Observable(findReviewsByItem)完成呢?

您可以使用BlockingObservable中的方法 看见 e、 g


另一种方法是在开始前声明倒计时锁存器。然后在onCompleted()中对该闩锁调用倒计时()。然后可以将该闩锁上的Thread.sleep()替换为wait()

您的大多数示例都可以使用标准的RxJava操作符重写,这些操作符可以很好地协同工作:

公共类示例{
调度器调度器=调度器。从(执行器);
公共可观测findReviewsByItem(最终字符串项){
可观察的返回。仅(项)
.subscribeOn(调度程序)
.flatMapIterable(reviewService::findReviewsByItem);
}
公共列表findWaresWithReviews(){
返回战争服务
.findWares()
.map(WareAndReview::新建)
.flatMap(wr->{
返回评论服务
.findReviewsByItem(wr.getWare().getItem())
.doOnNext(wr::addReview)
.lastOrDefault(空)
.地图(v->wr);
})
托利斯先生()
.toBlocking()
.first();
}
}
无论何时,只要您想编写这样的服务,请首先考虑
flatMap
。您不需要为每个子可观察对象进行阻塞,只需在最后使用
toBlocking()
即可

BlockingObservable.from(reviewService.findReviewsByItem(..)).toIterable()