在使用JerseyRx和RxMongo驱动程序编写Web爬虫时,我正在努力学习RxJava和Reactive编程。我的代码如下:
Observable.interval( 200, TimeUnit.MILLISECONDS ).map(tick -> links(linksCollection)
.map(linkDoc -> httpGet(client, linkDoc.getString("url"))
.map(htmlDoc -> parseLinks(htmlDoc)).subscribe() )
.subscribe())
.subscribe();
links()和httpGet()的签名如下:
Observable<Document> links(MongoCollection<Document> linkCollection)
Observable<String> httpGet(RxClient<RxObservableInvoker> client, String url)
List<HtmlLink> parseLinks(final String html)
假设方法在调用时打印它们的名称,则输出如下所示:
链接 得到 链接 解析 链接 链接 链接 链接
Get和Parse只被调用一次。 有人可以解释为什么程序流程就是这样以及如何解决这个问题。
在该问题中未声明的对象仅为了简洁而省略
答案 0 :(得分:2)
如果要触发异步子流程(比如获取链接的http文档),则应使用flatMap
。它将使子Observable变平并将其项目作为另一个连续的&#34;爆发&#34;产出中的排放量可见:
Observable.interval(200, TimeUnit.MILLISECONDS)
//this is a continuous flow of n documents repeated every 200ms:
.flatMap(tick -> links(linksCollection))
//this is a continous Observable<String> with n Strings every 200ms
.flatMap(linkDoc -> httpGet(client, linkDoc.getString("url"))
//here you have a flow of httpDocuments, get the list of links for each one
.map(htmlDoc -> parseLinks(htmlDoc);
将此链影响到变量会产生您可以订阅的Observable<List<HtmlLink>>
。