缓冲区为空时如何停止PublishSubject的发射

时间:2019-06-26 07:26:00

标签: android kotlin rx-java rx-java2 rx-android

我正在尝试使用RxJava创建顺序下载服务。 用户可以批量添加项目(20、30等)或单个项目。这些项目将添加到队列中,然后按10个批次的顺序下载。 为此,我正在使用PublishSubject:

PublishSubject<Int> pubSubject = PublishSubject.create();

发出用户添加的项目(id),然后将缓冲运算符应用于批处理项目。使用这些ID,可以在flatMap中下载项目,然后在订阅的onNext中返回。

  pubSubject.buffer(1, TimeUnit.SECONDS, 10)
            .observeOn(Schedulers.io())
            .flatMap { idsBatch -> downloadByIds(idsBatch) }
            .subscribe(
                /* onNext */ { apiResponse -> handleResponse() },
                /* onError */ { handleError(it) },
                /* onComplete*/ { hideProgressBar() }
             )

代码通常能按预期运行。项目已成功批处理并下载,但即使发出所有项目,缓冲区仍会使用空列表调用flatMap,并且永远不会调用onComplete()。

我想知道当缓冲区中没有更多项目时,RxJava中是否有任何方法或方法来获取onComplete回调。因为否则我的下载服务将永远不会终止。

1 个答案:

答案 0 :(得分:1)

您可以使用takeWhile操作:

  

返回一个Observable,它发射源ObservableSource发出的项目,只要每个项目满足指定条件,然后在不满足此条件时立即完成。

pubSubject.buffer(1, TimeUnit.SECONDS, 10)
          .observeOn(Schedulers.io())
          .takeWhile { idsBatch -> idsBatch.isNotEmpty() }
          .flatMap { idsBatch -> downloadByIds(idsBatch) }
          .subscribe(
              /* onNext */ { apiResponse -> handleResponse() },
              /* onError */ { handleError(it) },
              /* onComplete*/ { hideProgressBar() }
           )