Kotlin同步流动和收集
我有这样的代码,我想收集协程中api调用的结果,然后加入这个作业并从函数返回它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
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{…}
,它就会按照您的要求工作。