如何使用悬挂方法初始化ViewModel中的字段
如果我需要调用悬挂函数以获取值,如何初始化视图模型中的字段?
我有悬浮函数从数据库返回值。
suspend fun fetchProduct(): Product
当我创建视图模型时,我必须在此领域中获取产品
private val selectedProduct: Product
,我尝试这样做,但它不起作用,因为我在Coroutines之外称呼此方法
private val selectedProduct: Product = repository.fetchProduct()
How to initialize a field in view model if I need to call the suspend function to get the value?
I a have suspend function that returns value from a database.
suspend fun fetchProduct(): Product
When I create the view model I have to get product in this field
private val selectedProduct: Product
I tried doing it this way but it doesn't work because I'm calling this method outside of the coroutines
private val selectedProduct: Product = repository.fetchProduct()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于 fetchProduct() 是一个挂起函数,因此您必须在协程范围内调用它。
对于您的情况,我建议使用以下选项:
selectedProduct
定义为可为空,并将其在ViewModel
中初始化为null
:>lateinit var
并执行与上面相同的操作;就我个人而言,我更喜欢第一个,因为我觉得我可以更好地控制变量是否已定义这一事实。
Since
fetchProduct()
is a suspend function, you have to invoke it inside a coroutine scope.For you case I would suggest the following options:
selectedProduct
as nullable and initialize it inside yourViewModel
asnull
:lateinit var
and do the same as above;Personally I prefer the first cause I feel I have more control over the fact that the variable is defined or not.
您无法按照您描述的方式初始化字段。必须从协程或另一个
挂起
函数调用挂起
函数。要启动协程,有几个构建器:CoroutineScope.launch
、CoroutineScope.async
、runBlocking
。不建议在生产代码中使用后者。还有一些构建器 -liveData
、flow
- 可用于初始化字段。对于您的情况,我建议使用LiveData
< /a> 或Flow
来观察字段初始化。示例代码,它使用liveData
构建器函数调用suspend
函数:如果您想在初始化此字段后在 UI 中执行某些操作,则需要 观察它。在
Activity
或Fragment
中,它将如下所示:对于
liveData
,使用androidx.lifecycle:lifecycle-livedata-ktx: 2.4.0
或更高版本。You can't initialize a field in the way you described.
suspend
function must be called from a coroutine or anothersuspend
function. To launch a coroutine there are a couple of builders for that:CoroutineScope.launch
,CoroutineScope.async
,runBlocking
. The latter is not recommended to use in production code. There are also a couple of builders -liveData
,flow
- which can be used to initialize the field. For your case I would recommend to use aLiveData
orFlow
to observe the field initialization. The sample code, which uses theliveData
builder function to call asuspend
function:And if you want to do something in UI after this field is initialized you need to observe it. In
Activity
orFragment
it will look something like the following:For
liveData
, useandroidx.lifecycle:lifecycle-livedata-ktx:2.4.0
or higher.您需要在协程范围内运行该函数才能获取值。
如果您在 ViewModel() 类中,您可以安全地使用 viewModelScope
You need to run the function inside a coroutine scope to get the value.
if you're in a ViewModel() class you can safely use the viewModelScope