Rx java 自定义可观察的REST流来自链接列表

Rx java 自定义可观察的REST流来自链接列表,rx-java,Rx Java,我正在使用一个实现自己REST请求的库。它接受一个“permalink”并发出一个REST请求来获取内容(我在源代码中提供mock进行测试)。我有一个永久链接列表,希望为每个链接安排一个请求,并生成一个内容流结果。所有这些都应该是异步的,一旦所有的结果都完成了,我想发出它们的列表 我正试图使用RxJava实现这一点。下面是我现在拥有的(很抱歉没有使用lambdas,我只是想习惯RxJava类名): 公共类主{ 公共静态void main(字符串[]args){ 整数计数=10; List per

我正在使用一个实现自己REST请求的库。它接受一个“permalink”并发出一个REST请求来获取内容(我在源代码中提供mock进行测试)。我有一个永久链接列表,希望为每个链接安排一个请求,并生成一个内容流结果。所有这些都应该是异步的,一旦所有的结果都完成了,我想发出它们的列表

我正试图使用RxJava实现这一点。下面是我现在拥有的(很抱歉没有使用lambdas,我只是想习惯RxJava类名):

公共类主{
公共静态void main(字符串[]args){
整数计数=10;
List permalinks=新阵列列表(计数);
对于(int i=1;i
当从一个列表中创建一个Observable时,我是应该自己迭代列表,还是有其他更好的方法?例如,有Observable.from(Iterable),但我认为我不能使用它

您可以为每个链接构建一个可观察的对象,而不是在
create
方法中进行迭代

public Observable<Content> getContent(permalink) {

    return Observable.create(subscriber -> {
                   ContentManager cm = new ContentManager();
                   if (!subscriber.isUnsubscribed()) { 
                            cm.getBasicContentByPermalink(permalink, new RestCallback() {

                                @Override
                                public void onSuccess(Content content) {
                                        subscriber.onNext(content);
                                        subscriber.onCompleted();
                                }

                                @Override
                                public void onFailure(int code, String message) {
                                       subscriber.onError(OnErrorThrowable.addValueAsLastCause(new RuntimeException(message, permalink));
                                }

                }
    });
}
在发送REST请求之前,我正在检查isUnsubscribed,以及两个结果处理程序(成功/失败)中的isUnsubscribed。这是应该使用的方式吗

发送请求前检查是否取消订阅是一种方法。无法确定此成功/失败回调(我认为这没用,但有人可能会说我错了)

我实现了一些逻辑,在所有请求返回时调用onComplete,无论是成功还是失败(参见问题5)。但是,由于isUnsubscribed调用保护了这些请求,因此可能永远不会调用它们onComplete

如果您取消订阅流,您将停止观察流,因此您可能不会收到流完成的通知

例如,如果用户在发布内容的结果中未订阅,会发生什么?

您将能够在取消订阅之前使用发出的内容

在onFailure方法中,我使用onNext(null)发出null来标记失败。我这样做是因为最终我将有一个包含2个流的zip,并且仅当两个压缩值都为非null时才会发出自定义类的实例。这是正确的方法吗

否。不是null,而是发出错误(在订阅服务器上使用
onError
)。 使用此选项,您不必在zip lambda中检查null。只需zip

正如我所提到的,我有一些自定义逻辑来检查流是否完成。我在这里做的是计算其余结果,当处理的结果与列表中的永久链接一样多时,就完成了。这是必要的吗?这是正确的方法吗

如果要获取永久链接数,当流完成时,可以使用
count
运算符

Observable.from(permalinks)
          .flatMap(link -> getContent(link))
          .count()
          .subscribe(System.out::println);
如果要发出链接数,在成功链接结束时,可以尝试
scan
操作符

 Observable.from(permalinks)
           .flatMap(link -> getContent(link))
           .subscribe();
 Observable.from(permalinks)
          .flatMap(link -> getContent(link))
          .map(content -> 1) // map content to 1 in order to count it.
          .scan((seed, acu) -> acu + 1) 
          .subscribe(System.out::println); // will print 2, 3...

我自己从/flatMap尝试过,但我犯了一个错误,您的代码帮助我正确地完成了,我更喜欢这种方式,不需要我的自定义逻辑来检测完成,谢谢!在行subscriber.onError(OnErrorThrowable.addValueAsLastCause(new RuntimeException(“failed”),permalink);我在线程“thread-7”中得到:异常rx.exceptions.OneRorNotImplementedException:失败,从未看到流中的任何排放。我不认为这是正确的做法。我不会调用onNext,然后调用onCompleted,这将把permalink转换为0内容。我甚至不需要空值的过滤器。您应该使用OneRor而不是onCompleted来通知错误。如果要检测错误,需要实现onError回调:“Observable.error(新运行时异常(“oups”).subscribe(System.out::println,(e)->System.err.println(“error->”+e.getMessage());”。这将简化为管理流中的错误(使用onErrorResumeNext方法,…)toList只有在流完成时才会发出一个列表。因为它没有完成,所以不会发出列表。如果您想要一个已发出项目的部分列表,则必须将每个内容转换为一个包含一个项目的列表,然后使用扫描将其合并。它将发出一个列表,该列表在每次远程调用成功时都会增长。只需处理错误即可:可观察.from(permalinks).flatMap(link->getContent(link).doError(e->System.out.println)(“获取异常:”+e).onErrorResumeNext(Observable.empty())。此示例显示了对主流的网络调用错误。因此流将继续并忽略错误。getContent()流将停止,而不是“主流”。(请注意onerrorresumenext在getContent()流上!)。这是一种方法。否则:如何知道是否遇到错误或流是否已完成?
 Observable.from(permalinks)
          .flatMap(link -> getContent(link))
          .map(content -> 1) // map content to 1 in order to count it.
          .scan((seed, acu) -> acu + 1) 
          .subscribe(System.out::println); // will print 2, 3...