RxJava:为Completables

时间:2018-04-09 21:24:25

标签: java kotlin rx-java reactive-programming rx-java2

我试图查询为我提供要下载的文件列表的API(如下所示)。然后我继续下载这些文件,同时还要重新查询API以查找初始调用中可能遗漏的任何内容。

Completable#mergeDelayError(Iterable<? extends CompletableSource> sources)用于确保我可以并行执行多个任务,并在完成所有任务后收到通知。

fun fetchAndDownload(details: List<String>): Completable = 
    exampleApi.fetchPackages(details) // This is a Single
        .flatMapCompletable { (results, retry) -> 
            val completables = mutableListOf<Completable>()
            results.mapTo(completables) { value ->
                exampleApi.download(value).subscribeOn(Schedulers.io())
            }

            if (retry.isNotEmpty()) { 
                completables += fetchAndDownload(retry)
                    .delay(3L, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.io())
            }
            Completable.mergeDelayError(completables)
        }

但是,这种实现有可能通过一次执行太多事情来压倒网络和/或线程数。因此,我想知道限制一次运行的completables的最佳方法是什么。

我知道Completable#mergeDelayError(Publisher<? extends CompletableSource> sources, int maxConcurrency)但不确定如何将List<Completable>转换为所需的Publisher。另一种解决方案是提供具有最大线程数的自定义Scheduler,但我也不确定如何提供这样的Schduler(我可以在不再需要时清理和丢弃)

2 个答案:

答案 0 :(得分:2)

最简单的方法是使用Floable.fromIterableList Completable转换为Publisher

这将允许使用Completable#mergeDelayError(Publisher<? extends CompletableSource> sources, int maxConcurrency)

答案 1 :(得分:1)

您可以将 flatMap maxConcurrent 值一起使用,然后让您的管道同步运行。

  @Test
    public void asyncFlatMapWithMaxConcurrent() {
        Observable.from(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
                .flatMap(value -> Observable.just(value)
                        .map(number -> {
                            try {
                                Thread.sleep(1000);
                                System.out.println(String.format("Value %s in Thread execution:%s",number, Thread.currentThread().getName()));
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            return number;
                        }).subscribeOn(Schedulers.newThread())
                        , 2)//This is the max concurrenrt
        .subscribe();
        new TestSubscriber()
                .awaitTerminalEvent(15, TimeUnit.SECONDS);    }

如果你看到flatMap函数之后的第二个参数,我们传递一个值2,它是可以为该flatMap运行的最大并发线程数

您可以在此处查看示例等内容。

https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/transforming/ObservableFlatMap.java