Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在RxJava中进行递归可观察调用?_Java_Reactive Programming_Rx Java_Observable - Fatal编程技术网

如何在RxJava中进行递归可观察调用?

如何在RxJava中进行递归可观察调用?,java,reactive-programming,rx-java,observable,Java,Reactive Programming,Rx Java,Observable,我对(一般来说是反应性范式)是相当陌生的,所以请容忍我 假设我有这个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; } } pu

我对(一般来说是反应性范式)是相当陌生的,所以请容忍我

假设我有这个
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<Comment> for Comment with ID commentId
**

现在,如果我有
News n=News(99,[1,2])
,我如何递归地获取它的所有子级注释?i、 e.获取ID为[1,2,3,4,5,6]的评论? **

我寻找并偶然发现了这一点:

这是递归函数:

public class FileRecursion {
    static Observable<File> 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){
if(f.isDirectory())
返回Observable.from(f.listFiles()).flatMap(FileRecursion::listFiles);
可观察的返回。仅(f);
}
公共静态void main(字符串[]args){
Observable.just(新文件(“/Users/joschneider/Desktop”))
.flatMap(文件递归::列表文件)
.subscribe(f->System.out.println(f.getAbsolutePath());
}
}
它显示了一个如何执行递归可观察调用的示例,但内部函数(
f.listFiles()
)是一个阻塞操作(不返回另一个可观察调用)。在我的例子中,内部函数(
getComments
)是一个非阻塞函数,返回另一个可观察值。我该怎么做


任何帮助都将不胜感激。

这与文章中描述的几乎相同:

Observable<Comment> 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()));
}

你搞错了-
listFiles
确实返回了一个
可观察的
。嘿,你说得对!我怎么会不知道呢?好的,那么我如何实现这一点……嗯……哦,我是说内部函数
f.listFiles()
,它不返回可观测值,对吗?返回observable的是
FileRecursion::listFiles
。还是我遗漏了什么?你是对的-那是
File#listFiles
,它返回
File[]
。Egor,递归只得到了叶注释(即没有任何子项的注释)。看起来像是在递归函数中订阅了非叶注释。有什么想法吗?等等,我没有看到你更新的答案。让我先考虑一下。嗯,你说得对,我还没想过。我编辑了我的答案-现在
getInnerComments()
返回传递给它的注释,然后执行其他操作。@HoverPhoenix,等一下,我第一次阅读时不理解你的注释。让我打开我的IDE试试看。你真厉害,伊戈尔。成功了!我缺少的关键点是
flatMap
内部
flatMap
。此外,现在我明白了为什么需要运算符合并!非常感谢。我已经接受了你的帖子作为答案。是的,我刚刚测试过,效果很好。很高兴我能帮助你!。
Observable<Comment> 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()));
}
getNews(99)
        .flatMap(news -> Observable.from(news.commentIds))
        .flatMap(commentId -> getComments(commentId))
        .flatMap(comment -> getInnerComments(comment))
        .toList()
        .subscribe(commentList -> { });