我有一个项目列表,我需要提取一些值,并为每个项目进行api调用。要做到这一点,我使用如下_
Observable.from(myList)
.flatMap{ item ->
return serviceInteractor.uploadToServer(item)
}
.map { serverResponse ->
return serverResponse.getResponseCode
}
.toList()
.subscrible{ responseList ->
// do something with all the responses
}
好的,所以问题是,我不知道为什么所有的调用都是并行的。它不应该等待第一个响应,映射结果,从Observable.from()继续到下一个项目,并在最后返回responseMessages的最终列表吗?现在的情况是,所有的事情同时发生。为了确认这一点,如果我在toList
方法之前设置一个延迟(1,TimeUnit.Seconds),所有的事情都会同时发生,只有最后的onNext被延迟。
我怎样才能做到这一点?有一个id列表,要逐个上传到服务器,等待每一个完成,如果成功或失败进行下一步
flatMap
将"堆栈"调用。它将订阅每个Observable,然后按照它们到达的顺序发出结果。所以结果可能而不是被排序(参考文档)。
如果您希望结果是有序的,您应该查看concatMap
操作符。(见文档)
Observable.from(myList)
.concatMap{ item ->
return serviceInteractor.uploadToServer(item)
}
.map { serverResponse ->
return serverResponse.getResponseCode
}
.toList()
.subscrible{ responseList ->
// do something with all the responses
}
你可以通过这篇博文获得更多信息。
是的,你需要使用ConcatMap
Flat map使用merge操作符,而concatMap使用concat操作符。
那么序列将像这样
flatMap输出顺序为merged
concatMap输出序列为ordered
回答
在这里你可以看看这个例子
String arrData[] = {"0", "1", "2", "3", "4"};
Integer arrDelay[] = {1000, 6000, 4000, 9000, 2000};
Observable.from(arrData)
.concatMap(s -> Observable.from(arrData)
.delay(arrDelay[Integer.parseInt(s)],TimeUnit.MILLISECONDS))
.map(integer -> integer)
.toList()
.doOnCompleted(() -> Log.v("log", "doOnCompleted"))
.subscribe(integer -> Log.v("log", "" + integer));
在这里你可以检查延迟将arrDelay
项目的总数,因为我们已经使用了toList()
我知道我回答这个问题有点晚了