【问题标题】:My doOnComplete is called before .Map finsihes我的 doOnComplete 在 .Map 完成之前被调用
【发布时间】:2020-09-04 05:00:42
【问题描述】:

我对 kotlin observables 有疑问,我已经通过互联网和 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()

问题是 doFinally 和 doOnComplete 在 map 完成对所有 flowables 的迭代之前被调用。我尝试将 .zip 用于 flowables,但显然无法使其正常工作。

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

【问题讨论】:

    标签: android kotlin observable rx-android


    【解决方案1】:

    您应该使用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()
    

    【讨论】:

    • 谢谢,我现在就试一试,马上回来。
    • 我做了一些改变,但这为我指明了正确的方向。我现在将解决方案添加到我的问题中,以便有人会发现它有用。再次感谢。
    【解决方案2】:

    在查看 Eugene Popovich 的回答后。我被指出了正确的方向,然后我做了以下工作。

    所以,首先,我修改了我的函数以返回 Single Observable 的列表,而不是 Flowable 的列表,就像任何有意义的人一样。完成后,我按照 Eugene 的建议进行了操作,但只使用了 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()
    

    getCallsCountForWeek 的变化如下,基本上只是使用 single 而不是 Flowable,因为它更有意义,而 flatMapSingle 提供了开箱即用的分辨率,甚至无需调用 subscribe。

    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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-19
      • 2018-07-14
      • 1970-01-01
      • 2016-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-10
      相关资源
      最近更新 更多