Kotlin同步流动和收集

Kotlin同步流动和收集,kotlin,coroutine,flow,Kotlin,Coroutine,Flow,我有这样的代码,我想收集协程中api调用的结果,然后加入这个作业并从函数返回它 private suspend fun loadRangeInternal(offset: Int, limit: Int): List<Activity> { // load data from Room database // calling Retrofit request // and caching them if there is no d

我有这样的代码,我想收集协程中api调用的结果,然后加入这个作业并从函数返回它

 private suspend fun loadRangeInternal(offset: Int, limit: Int):  List<Activity> {

        // load data from Room database
        // calling Retrofit request
        // and caching them if there is no data available

        var activities: List<Activity> = listOf()

        val job = GlobalScope.launch {
            repo.loadActivitiesOf(settings.companyId, offset, limit)
                .collect {
                    networkError.send(it.error)

                    when (it.status) {
                        Resource.Status.SUCCESS -> {
                            activities = it.data ?: listOf()
                            isLoading.send(false)
                        }
                        Resource.Status.LOADING -> {
                            isLoading.send(true)
                        }
                        Resource.Status.ERROR -> {
                            isLoading.send(false)
                        }
                    }
                }
        }

        job.join()

        Timber.d("Activities loaded: $activities")

        return activities
    }
private-suspend-fun-loadRangeInternal(偏移量:Int,限制:Int):列表{
//从房间数据库加载数据
//呼叫改装请求
//并在没有可用数据时缓存它们
var活动:List=listOf()
val作业=GlobalScope.launch{
repo.loadActivitiesOf(settings.companyId、offset、limit)
.收集{
networkError.send(it.error)
何时(it.状态){
Resource.Status.SUCCESS->{
活动=it.data?:listOf()
isLoading.send(错误)
}
Resource.Status.LOADING->{
isLoading.send(真)
}
Resource.Status.ERROR->{
isLoading.send(错误)
}
}
}
}
job.join()
木材d(“装载的活动:$活动”)
返回活动
}

我还尝试使用async代替launch,使用Wait代替join

计算执行时间,方法是使用
measureTimeMillis{}
,并在此时延迟函数

private suspend fun loadRangeInternal(offset: Int, limit: Int):  List<Activity> {

        // load data from Room database
        // calling Retrofit request
        // and caching them if there is no data available

        var activities: List<Activity> = listOf()
 val executionTime = measureTimeMillis {
                    async {
                                repo.loadActivitiesOf(settings.companyId, offset, limit)
                                    .collect {
                                           networkError.send(it.error)

                                            when (it.status) {
                                              Resource.Status.SUCCESS -> {
                                                        activities = it.data ?: listOf()
                                                        isLoading.send(false)
                                               }
                                               Resource.Status.LOADING -> {
                                                        isLoading.send(true)
                                               }
                                               Resource.Status.ERROR -> {
                                                   isLoading.send(false)
                                             }
                                         }
                                 }
                      }.await()
                }
        delay(executionTime)
        Timber.d("Activities loaded: $activities")

        return activities
    }
private-suspend-fun-loadRangeInternal(偏移量:Int,限制:Int):列表{
//从房间数据库加载数据
//呼叫改装请求
//并在没有可用数据时缓存它们
var活动:List=listOf()
val executionTime=measureTimeMillis{
异步的{
repo.loadActivitiesOf(settings.companyId、offset、limit)
.收集{
networkError.send(it.error)
何时(it.状态){
Resource.Status.SUCCESS->{
活动=it.data?:listOf()
isLoading.send(错误)
}
Resource.Status.LOADING->{
isLoading.send(真)
}
Resource.Status.ERROR->{
isLoading.send(错误)
}
}
}
}.等待
}
延迟(执行时间)
木材d(“装载的活动:$活动”)
返回活动
}

使用
measureTimeMillis{}
计算执行时间,并在该时间延迟函数

private suspend fun loadRangeInternal(offset: Int, limit: Int):  List<Activity> {

        // load data from Room database
        // calling Retrofit request
        // and caching them if there is no data available

        var activities: List<Activity> = listOf()
 val executionTime = measureTimeMillis {
                    async {
                                repo.loadActivitiesOf(settings.companyId, offset, limit)
                                    .collect {
                                           networkError.send(it.error)

                                            when (it.status) {
                                              Resource.Status.SUCCESS -> {
                                                        activities = it.data ?: listOf()
                                                        isLoading.send(false)
                                               }
                                               Resource.Status.LOADING -> {
                                                        isLoading.send(true)
                                               }
                                               Resource.Status.ERROR -> {
                                                   isLoading.send(false)
                                             }
                                         }
                                 }
                      }.await()
                }
        delay(executionTime)
        Timber.d("Activities loaded: $activities")

        return activities
    }
private-suspend-fun-loadRangeInternal(偏移量:Int,限制:Int):列表{
//从房间数据库加载数据
//呼叫改装请求
//并在没有可用数据时缓存它们
var活动:List=listOf()
val executionTime=measureTimeMillis{
异步的{
repo.loadActivitiesOf(settings.companyId、offset、limit)
.收集{
networkError.send(it.error)
何时(it.状态){
Resource.Status.SUCCESS->{
活动=it.data?:listOf()
isLoading.send(错误)
}
Resource.Status.LOADING->{
isLoading.send(真)
}
Resource.Status.ERROR->{
isLoading.send(错误)
}
}
}
}.等待
}
延迟(执行时间)
木材d(“装载的活动:$活动”)
返回活动
}

它看起来像是黑客或用于测试的代码,目的是不准备生产?是的,对我来说也是黑客(ish)解决方案。我改为使用回调,但从.collect{}调用此回调。但我认为协同程序不需要回调是的,你是对的,这是一个黑客。我也没有发现太多有用的东西,所以我用它来测试我的一个函数它看起来像是用于测试的hack或代码,目的是不准备生产?是的,对我来说也是hack(ish)解决方案。我改为使用回调,但从.collect{}调用此回调,但我认为协程不需要回调是的,你说得对,这是一次黑客攻击。我也没有发现太多有用的东西,所以我就用它来测试我的一个函数。我不确定我是否理解为什么要把整个
GlobaleScope.launch{…}
job.join()
放在第一位。看起来,如果你删除它们,只需调用
.collect{…}
,它就会像你希望的那样工作。我不确定我是否理解一个理由,首先让整个
GlobaleScope.launch{…}
job.join()
。看起来,如果您删除它们,只需调用
.collect{…}
,它就会按照您的要求工作。