【问题标题】:Syncrhonize multiple api calls Android RxJava同步多个 api 调用 Android RxJava
【发布时间】:2021-02-02 00:57:46
【问题描述】:

我有 2 个 API 调用:

  • Call1:Observable<Product> -> 返回产品列表。
  • Call2:Observable<InfoProduct> -> 其他人返回来自产品的更多信息(给定 ID)(响应不包含产品的 ID)

我需要我们调用的产品列表,一旦我有了它,从第二个 api 调用中一一调用额外的信息。一旦我拥有了所有,我必须对所有数据进行 mnix 以获得“CompleteInfoProduct”列表

我能够得到Call1的信息,我终于实现了获取更多信息产品的列表(call2)。这就是问题所在,我不知道如何将 call2 与 call1 的一项“匹配”。

简化示例:

getProducts()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe { response ->
            if (response.success) {
                val productsId = response.products.map { it.id }

                val obversableListMoreInfoProducts = mutableListOf<Observable<MoreInfoProductResponse>>()

                productsId.forEach { productId ->
                    obversableListMoreInfoProducts.add(
                            this.model.getMoreInfoProduct(productId)
                    )
                }

                val sub = Observable.merge(obversableListMoreInfoProducts)
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .toList()
                        .subscribe { it ->
                            Logger.d("Size MoreInfoProducts: ${it.size}")
                            <HERE I HAVE THE LIST OF MORE INFO . THE PROBLEM IS THAT THIS MODDEL DONT HAVE THE ID OF THE PRODUCT, AND I DON'T KNWO HOW TO JOIN WITH IT>
                        }
                addSubscription(sub)
            }
        }

如何同步和混合所有信息?

【问题讨论】:

    标签: android rest rx-java2 rx-android


    【解决方案1】:

    最简单的解决方案可能如下所示:

    class SO64424129 {
        private fun getProducts(): Single<List<Int>> { // (1)
            return Single.just(listOf(1, 2, 3, 4)).delay(1, TimeUnit.SECONDS)
        }
    
        private fun getProductInfo(productId: Int): Single<String> { // (2)
            return Single.just("PI: $productId")
                .delay(Random().nextLong().rem(1000), TimeUnit.MILLISECONDS)
        }
    
        fun getFullProducts(): Single<List<String>> {
            return getProducts()
                .flatMap { ids ->
                    Observable.fromIterable(ids) // (3)
                        .flatMapSingle { productId ->
                            getProductInfo(productId)
                                .map {  productInfo -> "$productId $productInfo" } // (4)
                        }
                        .toList() // (5)
                }
        }
    }
    
    class SO64424129Test {
    
        @Test
        fun `when full products required then list of full products received`() {
            val tested = SO64424129()
    
            val testSubscription = tested.getFullProducts().test()
    
            testSubscription.await()
            testSubscription.assertValue { listOfProducts ->
                listOfProducts.containsAll(listOf("1 PI: 1", "2 PI: 2", "3 PI: 3", "4 PI: 4"))
            }
            testSubscription.assertNoErrors()
        }
    }
    

    有趣的部分:

    1. getProducts() 返回一个“产品 ids”列表,并有一些延迟以模仿真实的 API
    2. getProductInfo() 返回单品信息。为了简单起见,我只是将给定的 ID 转换为字符串"PI: $productId",但你可以为所欲为。
    3. 创建Observable 将给定的 id 列表作为单个项目(一项一项)发出。
    4. 结合 id (Product) 和产品信息字符串表示 (InfoProduct )
    5. toList() 等待 Complete 事件,合并所有发出的 ProductInfo,并将它们作为单个列表发出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-14
      • 1970-01-01
      • 2017-12-24
      • 2023-03-28
      • 1970-01-01
      • 2014-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多