如何从单

时间:2017-10-27 02:26:55

标签: retrofit2 rx-java2

我正在使用Rxjava的Retrofit来检索Single响应。

@GET("/commonapi/search")
Single<MyEntity> requestAddressRx(@Query("searchVal") String searchVal,
                                   @Query("pageNum") int pageNum);

我有一个将返回以下内容的json

{"found":240,"totalNumPages":16,"pageNum":1,"results":[...

目前,要检索所有16个页面,我必须执行以下操作: -

  1. 调用requestAddressRx()一次以获取totalNumPages的第一个结果,
  2. 然后创建一个单独的Flowable调用requestAddressRx()以从第2页循环到第16页。
  3. 有没有办法将第1步和第2步结合在一起?

    //在经历了一些笨拙之后 - 我现在拥有的是

        Single<List<MyEntity>> result =  addressRetrofitRx.requestAddressQueryRx(query, 1)
                //now i get the number of pages from the results
                //  -NOTE: the result is now discarded :(
                .map( r-> r.getTotalNumPages() ) 
                //now i create a flowable from the number of pages
                .flatMapPublisher(totalNumPages -> Flowable.range(1, totalNumPages))
                .flatMapSingle(pageNumber -> addressRetrofitRx.requestAddressQueryRx(query, pageNumber))
                .toList();
    

    这会导致Rxjava两次调用第1页(第一次读取并在读取totalNumPages后丢弃)。

    此外,如果结果只有1个totalNumPages,我仍然会生成可流动的。

    应该有更好的方法来解决这个问题,但我似乎无法弄明白。在结果中编码numberOfPages的JSON模式非常常见,所以我假设有正确的RxJava解析方法。

1 个答案:

答案 0 :(得分:1)

您不必绘制总页数,只需将第一页MyEntity与其他页面连在一起:

Single<List<MyEntity>> result =  api.requestAddressQueryRx(query, 1)
    //now i create a flowable from the number of pages
    .flatMapPublisher(r -> {
         Flowable<MyEntity> pages = Flowable.just(r);
         int maxPages = r.getTotalNumPages();
         if (maxPages > 1) {
             pages = pages
                 .concatWith(
                     Flowable.range(2, maxPages - 1)
                         .flatMapSingle(pageNumber ->
                             api.requestAddressQueryRx(query, pageNumber)
                         , /* eager error */ false, /* keep order of pages */ 1)
                 );
         }
         return pages;
     })
     .toList();