如何在Coroutine范围中返回价值?

发布于 2025-02-13 07:55:55 字数 1236 浏览 0 评论 0原文

是否可以在coroutine范围中返回值,而无需运行阻塞? 目前,我在存储库中的代码看起来像这样:

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

这是我的用户录取

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

}

碱基cassecase

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
}

...但是我当然知道这不是一个正确的解决方案。您将如何实现这一目标?在viewModels'或片段中,我可以直接使用 lifecyclescope“,但是在其他情况下,必须直接从下面的方法调用USECase。一直致电调度员是否有效?

CoroutineScope(Dispatchers.Main).launch { }

Is it possible to to return value in Coroutine Scope without run blocking?
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 uselifecycleScope`, but what in other cases, where the must is to call useCase directly from method below. Is it efficient to call Dispatchers.Main all the time?

CoroutineScope(Dispatchers.Main).launch { }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱格式化 2025-02-20 07:55:55

您可以将值从Coroutine传递给Livedata,然后使用观察者

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

,然后在Coroutine中进行:

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

然后在活动中:

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

You could just pass the value from a coroutine to liveData and then use an observer

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)
}
肥爪爪 2025-02-20 07:55:55

在悬挂功能中使用Runblocking是没有意义的。 (在一个项目中部分转换为使用Coroutines的项目中,除了作为Coroutines和非coroutine代码之间的桥梁之外,完全使用它几乎没有任何意义,但仍然需要支持遗留代码或库。

)你需要。

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

如果您需要指定调度程序,请使用 使用

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

但是,如果构建是暂停功能,则无需在调用时指定调度程序。暂停功能负责内部调用其在适当的线程/调度器上的功能。

如果您需要在Coroutine或悬挂功能内部的coroutine范围,请使用小写coroutinescope函数,该功能会创建一个范围,如果取消Coroutine,该范围将自动取消。这个示例没有多大意义,因为通常您不需要新的范围,除非您在其中运行并行作业:

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

It doesn't make sense to use runBlocking in a suspend function. (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:

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. 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. 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)
}
向日葵 2025-02-20 07:55:55

您是否曾经听过 lambda
它看起来像呼叫:( myResult) - &gt;单位
我不时使用它

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

Have you ever listened about a lambda?
It looks like 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)}
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文