Rx java 如何保证fromIterable之后的订阅顺序?

Rx java 如何保证fromIterable之后的订阅顺序?,rx-java,rx-java2,Rx Java,Rx Java2,这是一个简化的示例,但基本上可以归结为 Observable.just(listOfItems) .flatMapIterable { it } .flatMap { doWhatever() .subscribeOn(Schedulers.io()) } 我所观察到的,并且猜测它是有意义的,虽然iterable是按顺序连接的,但是doWhatever()是按随机顺序订阅的 有什么方法可以保证doWhatever订阅的顺序吗?我不

这是一个简化的示例,但基本上可以归结为

Observable.just(listOfItems)
    .flatMapIterable { it }
    .flatMap {
        doWhatever()
            .subscribeOn(Schedulers.io())
    }
我所观察到的,并且猜测它是有意义的,虽然iterable是按顺序连接的,但是
doWhatever()
是按随机顺序订阅的

有什么方法可以保证doWhatever订阅的顺序吗?我不想要concatMap,而concatMapEager似乎只对结果排序,而不是子订阅。基于指数的人工延迟?(似乎只有在延迟更高的情况下才可靠,无论如何,幻数-坏)

///

private val uploadSchedules=Schedulers.from(Executors.newFixedThreadPool(5))
乐趣上传(请求:请求):可完成{
可观察的。公正的(请求)
.flatMap{request->upload(request).subscribeOn(uploadScheduler)}
}
趣味上传(请求:列表):可完成{
可观察的。来自可观察的(请求)
//这里的订阅顺序是race-y,我希望它们按照列表的顺序排序--|
.flatMap{请求->上载(请求)|
.subscribeOn(上载计划程序)|

.doOnSubscribe{log(request)}使用单线程调度程序,如
Schedulers.single()
Schedulers.from()
Executors.newSingleThreadedExecutor()一起使用
例如。我预测你会抱怨这会一个接一个地运行所有的
dowhat
。我的回答是,为什么哪一个先运行都很重要?你如何检测订单?你如何知道下一次订阅何时发生?我实际上使用的是自定义计划程序(而不是IO)固定为5次并行上传。因此atmost 5应该一次上传,当一次上传完成后,等待的第6次应该开始上传。我使用scheduler来创建此限制,而不是flatMap maxConcurrency,因为还有一次上传,这是另一个功能,所以它们没有任何关联,并且全局上,正如我所说的,只有5次应该正在运行。订阅顺序对我来说很重要,列表中的前5个应该始终在前5个上载中,列表中的第6个不应该进入这5个。上载完成顺序(doWhatever)没关系。它应该知道它和concatMap做的一样,上游完成了。所以可以观察到的ListoItems是冷的和可完成的;它基本上是一个并行阻塞队列的情况,我知道这很难理解,希望现在更清楚,这对我来说听起来像
maxConcurrency
,但不是冷的,而是像一个通过使用主题来上传内容的热服务。单线程调度程序或maxConcurrency 1可以让您以一次上传不超过1次为代价获得有序执行。否则您可以获得重新排序。我仍然不明白为什么您不能使用序列化主题和下载说明,然后让flatMap与maxConcurrency一起完成其余的工作?
private val uploadSchedules = Schedulers.from(Executors.newFixedThreadPool(5))

fun upload(request: Request) : Completable {
      Observable.just(request)
         .flatMap { request -> upload(request).subscribeOn(uploadScheduler) }
}

fun upload(requests: List<Request>) : Completable {
      Observable.fromIterable(requests)
         // here the subscriptions order are race-y, I want to want them ordered by the order of the list--|
         .flatMap { request -> upload(request)                                                             |
                        .subscribeOn(uploadScheduler)                                                      |
                        .doOnSubscribe { log(request) }  <-------------------------------------------------|
         }
}

// log outputs:
// request 0
// request 3
// request 4
// request 2
// request 1
// etc, race-y, random order