简体   繁体   English

如何在协程范围内返回值?

[英]How to return value in coroutine scope?

Is it possible to to return value in Coroutine Scope without run blocking?是否可以在没有运行阻塞的情况下在Coroutine Scope中返回值? For now my code in repository looks like this:现在我在存储库中的代码如下所示:

    suspend fun getWorkItem(workItemId: Int): WorkItemRoom? {
        runBlocking {
            return@runBlocking
            CoroutineScope(Dispatchers.Main).launch {
                getWorkItemByIdUseCase.build(workItemId)
            }
        }
        return null
    }

this is my useCase这是我的用例

class GetWorkItemByIdUseCase(private val workItemDao: WorkItemDao) :
    BaseUseCase<Int, WorkItemRoom>() {
    override suspend fun create(id: Int): WorkItemRoom {
        return workItemDao.getWorkItemById(id)
    }

}

baseUseCase基本用例

abstract class BaseUseCase<P, R> {
    protected abstract suspend fun create(params: P): R
    open suspend fun build(params: P): R = create(params)
}

Dao

@Dao
abstract class WorkItemDao {

    @Query("SELECT * FROM workitem WHERE id=:id")
    abstract suspend fun getWorkItemById(id: Int): WorkItemRoom
}

... but certainly I know it is not a proper solution. ...但我当然知道这不是一个合适的解决方案。 How would you achieve this?您将如何实现这一目标? In viewmodels' or fragments I can directly use lifecycleScope`, but what in other cases, where the must is to call useCase directly from method below.viewmodels' or fragments I can directly use生命周期范围,但在其他情况下,必须直接从下面的方法调用 useCase。 Is it efficient to call Dispatchers.Main all the time?一直调用 Dispatchers.Main 是否有效?

CoroutineScope(Dispatchers.Main).launch { }

It doesn't make sense to use runBlocking in a suspend function.在挂起函数中使用runBlocking没有意义。 (It hardly ever makes sense to use it at all, except as a bridge between coroutines and non-coroutine code in a project that is partially converted to using coroutines but still needs to support legacy code or libraries.) (使用它几乎没有任何意义,除非在项目中作为协程和非协程代码之间的桥梁,该项目部分转换为使用协程但仍需要支持遗留代码或库。)

You should just call the function you need.你应该只调用你需要的函数。

suspend fun getWorkItem(workItemId: Int): WorkItemRoom? { //may not need nullable return value
    return getWorkItemByIdUseCase.build(workItemId)
}

If you need to specify a dispatcher, use withContext :如果需要指定调度程序,请使用withContext

suspend fun getWorkItem(workItemId: Int): WorkItemRoom? = withContext(Dispatchers.Main) { 
    getWorkItemByIdUseCase.build(workItemId)
}

However, if build is a suspend function, there's no need to specify a Dispatcher when calling it.但是,如果build是一个挂起函数,则在调用它时无需指定 Dispatcher。 Suspend functions are responsible for internally calling their functions on appropriate threads/dispatchers.挂起函数负责在适当的线程/调度程序上内部调用它们的函数。

If you need a coroutine scope inside a coroutine or suspend function, use the lowercase coroutineScope function, which creates a scope that will be automatically cancelled if the coroutine is cancelled.如果您需要在协程或挂起函数中使用协程作用域,请使用小写的coroutineScope函数,该函数会创建一个作用域,如果协程被取消,该作用域将自动取消。 This example doesn't make much sense, because normally you don't need a new scope unless you are running parallel jobs inside it:这个例子没有多大意义,因为通常你不需要一个新的范围,除非你在其中运行并行作业:

suspend fun getWorkItem(workItemId: Int): WorkItemRoom? = coroutineScope(Dispatchers.Main) { 
    getWorkItemByIdUseCase.build(workItemId)
}

You could just pass the value from a coroutine to liveData and then use an observer您可以将协程中的值传递给 liveData,然后使用观察者

private val observableMutableLiveData = MutableLiveData<Type>()
val observableLiveData: LiveData<Type> = observableMutableLiveData

and later in a coroutine:后来在协程中:

CoroutineScope(Dispatchers.Main).launch {
    observableMutableLiveData.postValue(value)
}

and then in an activity:然后在一个活动中:

viewModel.observableLiveData.observe(this) { Type ->
   Log.i("result", Type)
}

Have you ever listened about a lambda ?你听过lambda吗?
It looks like call: (MyResult) -> Unit看起来像call: (MyResult) -> Unit
I use it from time to time like我不时使用它

fun someToDo(call: (MyResult) -> Unit) {
    scope.launch(Dispatchers.IO) {
        val result = getFromSomeWere()
        launch(Dispatchers.Main){call(result)}
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM