android - 同步多个 api 调用 Android RxJava
问题描述
我有 2 个 API 调用:
- Call1:
Observable<Product>
-> One 返回产品列表。 - Call2:
Observable<InfoProduct>
-> Other 从产品返回更多信息(给定 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)
}
}
如何同步和混合所有信息?
解决方案
最简单的解决方案可能与此类似:
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()
}
}
有趣的部分:
getProducts()
返回一个“产品 ID”列表,并有一些延迟以模仿真实的 APIgetProductInfo()
返回单个产品信息。为了简单起见,我只是将给定的 ID 转换为 String"PI: $productId"
,但你可以做任何你想做的事情。- 创建
Observable
将给定 id 列表作为单个项目(一项一项)发出的内容。 - 结合 id (
Product
) 和产品信息字符串表示 (InfoProduct
) toList()
等待Complete
事件,组合所有发出ProductInfo
的 's,并将它们作为单个列表发出。
推荐阅读
- javascript - For循环之前的异步获取/获取请求
- r - R 代码:使用最陡下降求根
- python - Selenium Python for 循环仅获取第一项
- firebase - 没有为“FirebaseUser”类定义吸气剂“实例”
- sql - SQL - 加入或联合两个表检查重复项?
- java - 为什么我的 mysql 连接器 jar 文件不能从 eclipse 中访问,尽管我有 mysql 连接器 jar 文件的构建路径?
- ios - 图像出现在 Xcode 的模拟器中,但不在设备上
- julia - 在 Julia 中将十六进制字符串转换为 base64
- mysql - 使用 where 子句对 max 和 min 列进行 MySQL 索引
- graphql - 从strapi上的graphql响应中过滤敏感数据