我对kotlin观察点有一个问题,我已经通过互联网和stackoverflow搜索过了,但我认为我在概念上遗漏了一些东西。我有一个名为getCallsCountForWeek的dashboardRepository,它基本上返回了过去7天的可流动列表,现在我需要迭代所有的可流动对象,然后用用户当天的调用次数更新我的图形。以下是我的代码
fun getCallsCountForWeek(calendar: Calendar) : List<Flowable<Float>> {
val result = ArrayList<Flowable<Float>>()
for(index in 0..6) {
calendar.add(Calendar.DAY_OF_MONTH, -index)
result.add(dashbordDao.getCallsCountForDay(customSharedPreferences.getUser()?.id!!, CustomDateTimeUtil.getStartOfDay(calendar), CustomDateTimeUtil.getEndOfDay(calendar)).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()))
}
return result
}
Observable.fromArray(dashboardRepository
.getCallsCountForWeek(calendar). map {
items -> kotlin.run {
items.forEach {
it.subscribe({
Log.e("Result", " Count: " + it)
},{
Log.e("Error", "" + it)
})
}
}
}.doOnComplete {
//We will do this when it is completed
Log.e("Result", "Completed")
}.doFinally {
Log.e("Result", "Finally")
}.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe()
问题是,在map完成对所有可流动对象的迭代之前,会调用doFinally和doOnComplete。我尝试将.zip用于可流动对象,但显然也无法使其工作。
根据其他关于堆栈溢出的帖子,订阅成功时会调用doOnComplete,但我希望在.map内部完成所有工作后调用。
发布于 2020-09-04 07:24:22
您应该使用flatMap
或flatMapIterable
而不是map
,并且只有一个subscribe
调用
Observable.fromArray(dashboardRepository
.getCallsCountForWeek(calendar)
.flatMapIterable { it } // iterate over list
.flatMap { it } // use flowables from list
.doOnNext { /* do something with every item */ }
.doOnComplete {
//We will do this when it is completed
Log.e("Result", "Completed")
}
.doFinally {
Log.e("Result", "Finally")
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.ignoreElements () // if you already handled everything in the doOnNext
.subscribe()
发布于 2020-09-04 08:02:46
在调查了尤金·波波维奇的回答后。我被指引到正确的方向,然后我做了下面的事情,它起作用了。
所以,首先,我修改了我的函数,返回单个可观察对象的列表,而不是像任何有意义的人那样返回可流动对象的列表。完成后,我按照尤金的建议做了如下操作,但只使用了flatMapSingle而不是flatMap。
Observable.fromArray(dashboardRepository.getCallsCountForWeek(calendar))
.flatMapIterable { it } // iterate over list
.flatMapSingle {
it
}
.doOnNext {
barEtries.add( BarEntry(index++, it))
}
.doOnComplete {
//We will do this when it is completed
Log.e("Result", "Completed "+barEtries)
setBarChartData()
}
.doFinally {
Log.e("Result", "Finally")
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.ignoreElements () // if you already handled everything in the doOnNext
.subscribe()
订阅的变化如下所示,基本上只是使用single而不是Flowable,因为它更有意义,而且flatMapSingle提供了开箱即用的解决方案,甚至不需要调用getCallsCountForWeek。
fun getCallsCountForWeek(calendar: Calendar) : ArrayList<Single<Float>> {
val result = ArrayList<Single<Float>>()
for(index in 0..6) {
calendar.add(Calendar.DAY_OF_MONTH, -index)
result.add(dashbordDao.getCallsCountForDay(customSharedPreferences.getUser()?.id!!, CustomDateTimeUtil.getStartOfDay(calendar), CustomDateTimeUtil.getEndOfDay(calendar)).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()))
}
return result
}
https://stackoverflow.com/questions/63735094
复制相似问题