使RxJava操作符链并发
我刚刚开始使用RxJava。我一直在尝试构建一个数据管道,从不同来源下载大量数据,并以并发方式将数据插入数据库 我的基本管道表单如下所示:使RxJava操作符链并发,java,asynchronous,reactive-programming,rx-java,Java,Asynchronous,Reactive Programming,Rx Java,我刚刚开始使用RxJava。我一直在尝试构建一个数据管道,从不同来源下载大量数据,并以并发方式将数据插入数据库 我的基本管道表单如下所示: Observable.range(1, 5) .concatMap((i) -> { return Observable.range(i, 2); }) .concatMap((i) -> { r
Observable.range(1, 5)
.concatMap((i) -> {
return Observable.range(i, 2);
})
.concatMap((i) -> {
return Observable.range(i, 2);
})
.subscribe((i) -> { System.out.println(i); }, System.out::println,() -> { System.out.println("Complete"); });
每当我调用observeOn而不是运行并打印出上面打印出的所有数字时,都不会打印出任何内容。为什么会这样?我希望下一个concatMap和subscribe也会使用计算调度器。代码发布在下面
Observable.range(1, 5)
.concatMap((i) -> {
return Observable.range(i, 2);
})
.observeOn(Schedulers.computation())
.concatMap((i) -> {
return Observable.range(i, 2);
})
.subscribe((i) -> { System.out.println(i); }, System.out::println,() -> { System.out.println("Complete"); });
这是一个猜测,因为您没有提供上下文,但如果您正在更改线程,则必须进行阻止,因为main未被阻止,并且您可能在其他计划程序运行之前终止:
Observable.range(1, 5)
.concatMap((i) -> {
return Observable.range(i, 2);
})
.observeOn(Schedulers.computation())
.concatMap((i) -> {
return Observable.range(i, 2);
})
.subscribe((i) -> { System.out.println(i); }, System.out::println,() -> { System.out.println("Complete"); });
// block to let other schedulers finish
Thread.sleep(3000);
在阅读您的注释以获取更多上下文之后,我假设您希望发出请求以获取id列表(项目摘要),然后对每个返回的id发出一个额外的请求以获取每个项目的详细信息,然后对结果(项目)进行处理 考虑到您已经有了生成和激发请求的方法,返回一个可观察的
。如果您的http库返回Future
s,您可以包装与http相关的代码并从中延迟可观察的内容,或者从Future
创建可观察的内容
// you have this available
Observable<Summary> = querySummary(summaryId);
Observable<Item> = queryItem(itemId);
如果要触发摘要请求并异步等待它,那么在新项目ID到达时也会同时触发项目的请求,您可以像这样添加.observeOn(Schedulers.io())
Observable<Item> itemsObservable = querySummary(summaryId)
.observeOn(Schedulers.io()) // from here, continue in the background
.flatMap(summary -> { // ...
或者
有很多不同的方法可以组合观察对象,创建一个或多个流,合并它们,异步或不异步运行它们。所以,这取决于你的需要
我希望有帮助 是的,这就是问题所在。是否有调度程序可以在调用代码的主线程上调度运算符?我查看了文档,没有看到任何与我需要的内容类似的内容。请尝试使用
调度器.immediate()
或使用Observable.toblock()
。尝试使用immediate,不起作用。我基本上是想让上面的代码等到观测者都完成了,而不需要任意睡眠。我认为可能会创建一个线程池,将其传递到Executor接口,然后等待线程池完成。这里仍然缺少上下文。这是一个x-y问题。如果您正在等待多个可观察对象,您可能应该Observable.merge()
将它们合并,然后通过阻塞等待它们完成?可以使用countdownlock
来阻止主线程,并使用Observable.doOnComplete()
从Observable.doOnComplete()来倒计时?根据上下文的不同,这里可以使用许多策略。感谢您的帮助Reut!
itemsObservable.doOnNext(item -> {
// do something in whatever thread it might be running
}).subscribe();
Observable<Item> itemsObservable = querySummary(summaryId)
.observeOn(Schedulers.io()) // from here, continue in the background
.flatMap(summary -> { // ...
itemsObservable
.toBlocking()
.subscribe(item -> {
// blocking the main thread
// do something on each item
});
itemsObservable
.toList()
.subscribe(itemsList -> {
// blocking the main thread
// do something with the whole list at once
});