Rx java RxJava异步while循环

Rx java RxJava异步while循环,rx-java,Rx Java,我想使用RxJava在Java中实现异步while循环 更具体地说,以下是我的非异步Java代码: for (String dataCenter : dataCenters) { final Set<Server> serversInDataCenter = getServersInDataCenterSync(dataCenter); if (!CollectionUtils.isEmpty(serversInDataCenter)) {

我想使用RxJava在Java中实现异步while循环

更具体地说,以下是我的非异步Java代码:

    for (String dataCenter : dataCenters) {
        final Set<Server> serversInDataCenter = getServersInDataCenterSync(dataCenter);
        if (!CollectionUtils.isEmpty(serversInDataCenter)) {
            final Server available = findOneWithSlots(serversInDataCenter);
            if (available != null) {
                return available;
            }
        }
        // if no available server found for current dataCenter, try next
    }
    return null;
for(字符串数据中心:数据中心){
最终设置serversInDataCenter=getServersInDataCenterSync(数据中心);
如果(!CollectionUtils.isEmpty(serversInDataCenter)){
最终可用服务器=findOneWithSlots(serversInDataCenter);
如果(可用!=null){
返回可用;
}
}
//如果找不到当前数据中心的可用服务器,请尝试下一步
}
返回null;
上面的代码所做的是从数据中心查找可用的服务器

由于90%的情况下,检查的第一个数据中心将有一个可用的服务器,我不想提前获取所有数据中心的所有服务器

现在,想象一下
Set getServersInDataCenterSync(String数据中心)
方法被更改为异步方法,并接受回调:
void getServersInDataCenter(String数据中心,AsyncResultHandler)
。这也是另一件事

Observable.fromIterable(dataCenters) // emits data center names
    .flatMap(name -> getServersInDataCenter(name), // returns Observable<Server>
        maxConcurrency) // see note below
    .filter(Server::hasSlotsAvailable) // pass through only available ones
    .take(1) // take first one and unsubscribe
使用
maxConcurrency
参数可以限制并发异步请求的数量。如果在检查第一个数据中心的所有服务器之前不想发出第二个请求,请将其设置为1。若您想在剩下的服务器不多的情况下加快查找可用服务器的速度,请增加它。您可能还需要使用
delayErrors
参数(参见文档)

Observable<Server> getServersInDataCenter(String name) {
    return Observable.create(emitter ->
        getServersInDataCenterAsync(name, event -> {
            if (event.isError()) 
                emitter.onError(event.getError());
            else {
                emitter.onNext(event.getResultSet()); // emit Set<Server>
                emitter.onComplete();
            }
        })
        .flatMapIterable(set -> set); // flatten Set into individual items
}