在我的应用程序中,我有两个服务,并且它们都有一个方法,该方法发出请求,然后返回不同类型的Observable。
我想在RecyclerView中显示一个列表,该列表由这两个Observable的组合结果组成。我对此进行了谷歌搜索,发现zip()方法似乎完全符合我的要求。我正在尝试实施它,但我不知道如何正确执行。
在谷歌搜索时,我想到了这个this article,似乎可以清楚地解释它。即使作者在使用Observables时使用Singles。
据我了解zip()
的工作原理,我知道我必须传递要“压缩”的每个Observable,然后必须指定一个函数来构成最终的Observable,对吗?
到目前为止,这是我的代码:
interface InvitationService {
@GET("foo/{userId}")
fun getFooByUser(@Path("userId") userId: String): Observable<Response<ArrayList<Foo>>>
}
interface InvitationService {
@GET("bar/{userId}")
fun getBarByUser(@Path("userId") userId: String): Observable<Response<ArrayList<Bar>>>
}
class FooRemoteDataSource : FooDataSource {
private var apiService: FooService
fun getFooByUser(userId:String) {
return apiService.getFooByUser(userId)
}
}
class BarRemoteDataSource : BarDataSource {
private var apiService: BarService
fun getBarByUser(userId:String) {
return apiService.getBarByUser(userId)
}
}
class FooRepository(private val remoteDataSource: InvitationRemoteDataSource) : FooDataSource {
override fun getFooByUser(userId: String): Observable<Response<ArrayList<Foo>>> {
return remoteDataSource.getFooByUser(userId)
}
}
class BarRepository(private val remoteDataSource: BarRemoteDataSource) : BarDataSource {
override fun getBarByUser(userId: String): Observable<Response<ArrayList<Bar>>> {
return remoteDataSource.getBarByUser(userId)
}
}
这是我实际遇到的地方:
class ListPresenter(var listFragment: ListContract.View?,
val fooRepository: FooRepository,
val barRepository: BarRepository) : ListContract.Presenter {
fun start() {
loadList()
}
private fun loadLists() {
//HERE IS WHERE IM STUCK
Observable.zip(fooRepository.getFooByUser(userId).subscribeOn(Schedulers.io()),
barRepository.getBarByUser(userId).subscribeOn(Schedulers.io()),
)
// AFTER 'ZIPPING' THE OBSERVABLES
// I NEED TO UPDATE THE VIEW ACCORDINGLY
}
}
我不知道如何正确调用zip()
,我知道我必须传递一个函数,但我不明白,因为在上面链接的文章中作者使用的是Function3
,因为他有3个可观察值
由于我只有2个,所以我不知道该怎么做。如果方法args内的逗号后有花括号,则需要我返回BiFunction<ArrayList<Foo>, ArrayList<Bar>>
,这是我不知道如何指定的。
有人会向我解释吗?
答案 0 :(得分:2)
对于Kotlin,您应该使用RxKotlin而不是RxJava。 BiFunction
,Function3
来自RxJava。借助RxKotlin,您可以改用lambda。
据我了解zip()的工作原理,我知道我必须传递我要“压缩”的每个Observable,然后必须指定一个组成最终Observable的函数,对吗?
正确,这是一个最小的示例,演示了如何做到这一点。
示例1
val observable1 = listOf(1, 2, 3).toObservable()
val observable2 = listOf(4, 5, 6).toObservable()
val zipped = Observables.zip(observable1, observable2) { o1, o2 -> o1 * o2}
在此示例中,您有两个可观察值,每个可观察值都发出整数。您将它们传递给zip
,并将其作为第三个参数传递一个lambda,该lambda定义了“合并它们”的方法。在这种情况下,它将它们相乘。
结果可观察到的zipped
将发出:4、10和18。
示例2
在另一个示例中,将三个并非相同类型的可观察对象压缩在一起:
val obs1 = listOf("on", "tw", "thre").toObservable()
val obs2 = listOf("n", "o", "e").toObservable()
val obs3 = listOf(1, 2, 3).toObservable()
val zipped = Observables.zip(obs1, obs2, obs3) { o1, o2, o3 ->
"$o1$o2 = $o3"
}
这里,可观察结果的每个元素将是一个字符串:“一个= 1”,“两个= 2”,“三个= 3”
答案 1 :(得分:1)
使用BiFunction压缩两个不同类型的Observable
override fun getCommoditiesAndAddresses() {
view.showProgress()
view.hideViews()
Observable.zip(Commo24Retrofit.createAuthService(RateAPIService::class.java)
.getCommodities(),
Commo24Retrofit.createAuthService(RateAPIService::class.java)
.getLocations(GetLocationsRequest(getOrgId())),
BiFunction { commodityResponse: GetCommoditiesResponse, locationsResponse: GetLocationsResponse ->
handleCommoditiesAndAddresses(commodityResponse, locationsResponse)
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
view.hideProgress()
view.showViews()
view.handleCommodities(it?.commodities)
view.handleLocations(it?.locations)
}, { throwable ->
view.hideProgress()
view.handleFailure(throwable.getErrorMessage(context))
})
}
看,我如何处理响应:
private fun handleCommoditiesAndAddresses(commodityResponse: GetCommoditiesResponse, locationsResponse: GetLocationsResponse): CommoditiesAddresses {
return CommoditiesAddresses(commodityResponse.commodityList, locationsResponse.addressList)
}
在这里,检查API服务:
interface RateAPIService {
@POST("get-org-address")
fun getLocations(@Body getLocationsRequest: GetLocationsRequest): Observable<GetLocationsResponse>
@POST("get-commodity-list")
fun getCommodities(): Observable<GetCommoditiesResponse>
}
如果有任何疑问,可以将其注释掉。