问题描述
- Call1:
Observable<Product>
->一个返回产品列表。 - Call2:
Observable<InfoProduct>
->“其他”从产品(给出ID)返回更多信息(响应不包含该产品的ID)
我需要我们调用的产品列表,一旦获得,就一次调用第二个api调用中的额外信息。一旦掌握了所有信息,就必须对所有数据进行混合以获取“ 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”列表,但要延迟一段时间才能模仿真实的API -
getProductInfo()
返回单个产品信息。为了简单起见,我只是将给定的ID转换为字符串"PI: $productId"
,但是您可以做任何您想做的事情。 - 创建
Observable
,将发出给定ID的列表作为单个项(一个一个)发出。 - 组合ID(
Product
)和产品信息字符串表示形式(InfoProduct
) -
toList()
等待Complete
事件,合并所有发出的ProductInfo
,并将它们作为单个列表发出。