如何在RxJava中执行递归可观察调用?
我对RxJava (以及一般的反应范式) 都很陌生 ,所以请耐心等待。
假设我有这个News
和这个嵌套的Comment
数据结构:
public class News { public int id; public int[] commentIds; //only top level comments public News(int id, int[] commentIds) { this.id = id; this.commentIds = commentIds; } } public class Comment { public int id; public int parentId; //ID of parent News or parent comment public int[] childIds; public Comment(int id, int parentId, int[] childIds) { this.id = id; this.parentId = parentId; this.childIds = childIds; } }
并假设我有这个API端点:
getComments(int commentId) //return Observable for Comment with ID commentId
现在,让我们假设:
getComments(1); //will return Comment(1, 99, [3,4]) getComments(2); //will return Comment(2, 99, [5,6]) getComments(3); //will return Comment(3, 1, []) getComments(4); //will return Comment(4, 1, []) getComments(5); //will return Comment(5, 2, []) getComments(6); //will return Comment(6, 2, [])
**
现在,如果我有News n = News(99, [1,2])
,我如何让它的所有孩子递归评论? 即获得ID [1,2,3,4,5,6]的评论?
**
我搜索并偶然发现了这个问题: https : //jkschneider.github.io/blog/2014/recursive-observables-with-rxjava.html
这是递归函数:
public class FileRecursion { static Observable listFiles(File f) { if(f.isDirectory()) return Observable.from(f.listFiles()).flatMap(FileRecursion::listFiles); return Observable.just(f); } public static void main(String[] args) { Observable.just(new File("/Users/joschneider/Desktop")) .flatMap(FileRecursion::listFiles) .subscribe(f -> System.out.println(f.getAbsolutePath())); } }
它显示了如何进行递归可观察调用的示例,但内部函数( f.listFiles()
)是一个阻塞操作(不返回另一个Observable)。 在我的例子中,内部函数( getComments
)是一个非阻塞函数,它返回另一个Observables。 我怎么做?
任何帮助都感激不尽。
这几乎与文章中描述的内容相同:
Observable getInnerComments(Comment comment) { if (comment.childIds.length > 0) return Observable.merge( Observable.just(comment), Observable.from(comment.childIds) .flatMap(id -> getComments(id)) .flatMap(this::getInnerComments)); return Observable.just(comment); } public static void main(String[] args) { getComments(1) .flatMap(this::getInnerComments) .subscribe(c -> System.out.println(comment.toString())); }
我从id = 1的注释开始,然后将其传递给getInnerComments()
。 getInnerComments()
检查注释是否有子项。 如果是,则迭代每个子ID( Observable#from
)并使用getComments(int)
API加载每个子ID。 然后将每个子getInnerComments()
传递给getInnerComments()
以执行相同的过程。 如果注释没有子项,则立即使用Observable#just
返回。
这是伪代码,它没有经过测试,但你应该明白这个想法。
下面是如何获取所有注释然后将它们聚合到一个List
的示例。
getNews(99) .flatMap(news -> Observable.from(news.commentIds)) .flatMap(commentId -> getComments(commentId)) .flatMap(comment -> getInnerComments(comment)) .toList() .subscribe(commentList -> { });
- 使用maven-assembly-plugin创建两个可执行的jar
- 如果在同一帧-Java中有多个JPanel,我如何在特定的JPanel中绘制
- java.lang.NoClassDefFoundError:org / hibernate / cache / EntityRegion配置EHCache
- Maven Update Project究竟在Eclipse中做了什么?
- EasyMock和测试受保护的方法
- Java包装类真的是不可变的吗?
- 如何在最短的时间内在java中克隆输入流
- 如何配置EasyMock Class Extension 3.1?
- JSP – 如何在session.setAttribute中传递javascript var?