android RxJava Observable.from发布到服务

时间:2016-08-17 13:38:10

标签: android rx-java retrofit2

我有一个项目列表,我需要提取一些值并为每个项目进行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列表,想要逐个上传到服务器,等待每一个完成,如果成功或失败则继续下一个

2 个答案:

答案 0 :(得分:1)

flatMap会“堆叠”来电。它将订阅每个Observable然后按其到达顺序发出结果。因此,结果可能被排序(cf documentation)。

如果您想要对结果进行排序,则应该查看concatMap运算符。(请参阅documentation

Observable.from(myList)
     .concatMap{ item ->
              return serviceInteractor.uploadToServer(item)
      }
     .map { serverResponse ->
         return serverResponse.getResponseCode
      }
     .toList()
     .subscrible{ responseList ->
         // do something with all the responses
     }

您可以通过this blog post.

获取更多信息

答案 1 :(得分:0)

是的,您需要使用ConcatMap

平面地图使用merge operator,而concatMap使用concat opertor

所以序列就像这样

flatMap输出序列为merged
concatMap输出序列为ordered

如此answer

中所述

在这里你可以看看这个例子

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()

我知道我迟到了回答:)