我的doOnComplete在.Map修饰之前被调用

问题描述

我对kotlin可观察变量有疑问,我已经通过Internet和stackoverflow搜索过,但是我认为我在概念上缺少一些东西。我有dashboardRepository,它具有名为getCallsCountForWeek的方法,这基本上返回了过去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通过所有flowable完成迭代之前,将调用doFinally和doOnComplete。我尝试将.zip用于flowables,但显然也无法使其正常工作。

根据堆栈溢出的其他帖子,订阅成功时将调用doOnComplete,但我希望在.map内完成所有操作后发生这种情况。

解决方法

您应该使用flatMapflatMapIterable而不是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()
,

调查了尤金·波波维奇的回答。我被指出正确的方向,然后执行了以下操作,它就起作用了。

所以,第一件事,我修改了函数以返回Single Observable列表,而不是Flowable列表,因为任何有矿石意义的人都可以。完成后,我按照Eugene的建议进行了跟踪,但是只使用了flatMapSingle而不是flatMap。

--watch

getCallsCountForWeek中的更改如下所示,基本上只使用了Single而不是Flowable,因为这样做更有意义,并且flatMapSingle提供了开箱即用的分辨率,而无需调用甚至订阅。

    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()