如何在RxJava中进行递归可观察调用? [英] How To Do Recursive Observable Call in RxJava?

查看:164
本文介绍了如何在RxJava中进行递归可观察调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 RxJava (和一般的Reactive范式)很陌生,所以请多多包涵.

I am quite new to RxJava (and Reactive paradigm in general), so please bear with me.

假设我有这个News和这个嵌套的Comment数据结构:

Suppose I have this News and this nested Comment data structure:

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端点:

and suppose I have this API endpoint:

getComments(int commentId) //return Observable<Comment> 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, [])

**

**

我已经搜索并偶然发现: https://jkschneider.github.io/blog/2014/recursive-observables-with-rxjava.html

I have searched and stumbled upon this: https://jkschneider.github.io/blog/2014/recursive-observables-with-rxjava.html

这是递归函数:

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.listFiles())是阻塞操作(不会返回另一个Observable).就我而言,内部函数(getComments)是一个非阻塞函数,它返回另一个Observables.我该怎么办?

It shows an example on how to do recursive observable calls, but the inner function (f.listFiles()) is a blocking operation (doesn't return another Observable). In my case, the inner function (getComments) is a non-blocking function that returns another Observables. How do I do that?

任何帮助将不胜感激.

推荐答案

这实际上与文章中所述的相同:

This does practically the same thing described in the article:

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

我从id = 1的注释开始,然后将其传递给getInnerComments(). getInnerComments()检查注释是否包含子项.如果是这样,它将遍历每个子ID(Observable#from),并使用您的getComments(int) API加载每个子ID.然后,每个孩子都被传递到getInnerComments()以执行相同的过程.如果注释中没有子注释,则会立即使用Observable#just返回.

I start with the comment with id = 1, then I pass it to getInnerComments(). The getInnerComments() checks if the comment has children. If it does, it iterates over every child id (Observable#from) and loads every child with your getComments(int) API. Then every child is passed to the getInnerComments() to do the same procedure. If a comment doesn't have children, it is immediately returned using Observable#just.

这是伪代码,未经测试,但是您应该明白这一点.

This is pseudo-code and it wasn't tested, but you should get the idea.

下面是一个如何获取所有注释,然后将它们聚合为一个List<Comment>的示例.

Below is an example of how to get all comments and then aggregate them to one List<Comment>.

getNews(99)
        .flatMap(news -> Observable.from(news.commentIds))
        .flatMap(commentId -> getComments(commentId))
        .flatMap(comment -> getInnerComments(comment))
        .toList()
        .subscribe(commentList -> { });

这篇关于如何在RxJava中进行递归可观察调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆