android - android kotlin CoroutineScope 在一个完全完成后运行另一个
问题描述
我有一个片段,它有两个协程启动功能,一个从网络/数据库中获取数据
另一种是检查房间是否是空的并向用户显示一个弹出窗口。
功能
//this function gets the data
private fun initUI() = launch {
val data = viewModel.data.await()
data.observe(this@fragment, Observer {
if (it == null){
Log.d(TAG, "initui observer is null")
return@Observer
}
adapter = StoreAdapter(it, activity.baseContext)
recyclerView.adapter = adapter
activity.progressDisplay()
})
checkData().join()
}
//this function is designed to go after initUI()
private fun checkData() = launch {
delay(3000L) //temp solution
val check = viewModel.check.await()
Log.d(TAG, "$check")
if(check == 0L){
activity.showPopup(getString(R.string.error_text), getString(R.string.data_error), retry = true)
}
}
如果我只是 checkData().join() 如果数据库中没有数据开始,它会给我我的弹出窗口,然后在它之后工作正常。所以我增加了 3 秒的延迟,但是我不喜欢这种方式,但不确定是否还有其他方式?
@编辑
视图模型只是做一个 Lazy Defered 调用我的存储库
回购初始化
init {
source.downloadedData.observeForever { data->
saveData(data)
}
}
viewmodel.data 存储库代码
override suspend fun getData(): LiveData<List<item>> {
return withContext(Dispatchers.IO) {
initJsonData()
return@withContext myDao.getAll()
}
}
initJsonData 是一个检查日期函数,如果为 true,则从网络返回数据。
一旦我们创建了 init repo,我们就会永远观察来自网络的数据,并根据需要将其保存到房间 dB。
视图模型检查代码 在某种程度上遵循与获取数据相同的逻辑,但我只是从房间表中进行选择计数并返回结果。
override suspend fun checkData(): Long {
return withContext(Dispatchers.IO) {
Log.i(TAG, "checkData")
isDataEmpty()
}
}
解决方案
您有一个Observer
永远在观察下载的数据,当它观察到数据时,它会继续将其保存在您的数据库中。但是请记住,这并不能保证在saveData(data)
获取数据的代码之后立即调用此观察者(即)内部的代码,所以让我们将其分解如下:
当您调用
initUI()
方法时,第一行代码会获取数据并等待数据仅被获取而不是等待它被保存。在那之后,你
checkData()
和你saveData(data)
将竞相同时执行他们的逻辑。可悲的是,在saveData()
将任何内容保存在数据库中之前,checkData()
将错误返回给您。
一种解决方案是saveData()
在您获取它之后并在调用checkData().join()
同一个协程之前,如下所示:
private fun initUI() = launch {
val data = viewModel.data.await()
//Some other codes...
saveData(data.value) //If it's an asynchronous function, await for it.
checkData().join()
}
请注意,如果saveData(data)
是异步的,你必须await
为它。
推荐阅读
- reactjs - 将 URL 路径指定为手动构建的 REACT SSR 应用程序的变量(即不使用 NextJS )
- javascript - 如何创建多个嵌套列表
- json - NiFi - 将 json 中的逗号分隔字符串转换为数组
- python - 如何将具有命令行功能的 Python 包从 bash 迁移到 zsh
- listbox - OfficeJS 从下拉列表内容控件中读取文本
- python - 如何在不截断旧数据的情况下从 pandas 数据框中追加一个表
- shiny - 当我在下拉菜单中选择输入值时,输出结果不会改变
- javascript - 在可见性切换上调整 div 的大小(在 HTML + 纯 JS 中)?
- python - IndexError:从pygame中的空列表中弹出
- google-apps-script - 有没有办法从电子表格中的联系人列表生成 gmail 草稿?