Kotlin 协程:类 RxJava 订阅 运行 作业/检查协程是否为 运行
Kotlin Coroutines: RxJava-like subscribe to running job / Check if coroutine is running
我有以下设置(简化):
- 网络管理员(从后端获取数据)
- 存储库(处理数据并转发到 ui)
我正在寻找一种方法来使用协程执行以下操作:
- 在到达目标屏幕之前,我已经在导航到另一个屏幕时开始预取数据。
- 到达目标屏幕时,我想检查任务是否仍在 运行,如果是,"subscribe" 或等待结果,而不是开始新的冗余网络作业。
有没有办法用协程实现这个?
协程很热门,因此您可以通过在 background 或 UI 上下文中启动任务来推送数据:
job = launch(CommonPool) {
val data = getDataFromBackend().await()
val result = repository.handleData(data).await()
launch(UI) {
// update the UI here based on data or result
}
}
解决方法如下:
当应用程序启动时,它会触发通过存储库预取一些数据。
存储库包含对 运行 协程的作业引用。
当到达目标屏幕时,调用存储库中的另一个方法。在此方法中,应用程序现在只需检查作业是否仍处于活动状态,如果是,它会调用 job.join() 以等待执行完成后再继续。
这是问题的简化。请只关注问题的解决方案:
- 启动协程,
- 检查协程是否仍然是 运行,
- 如果是,在执行其他逻辑之前等待协程完成
在存储库中它看起来如下:
class Repository(private val networkManager: NetworkManager) {
private var allObjectsJob: Job? = null
fun getAllObjects(forceReload: Boolean = false) {
allObjectsJob = launch {
try {
val objects = networkManager.getAllObjects().await().filterNotNull()
// e.g. put all objects in map
} catch (e: HttpException) {
// error handling
}
}
}
fun getObject(id: String) {
launch {
if (allObjectsJob != null && allObjectsJob!!.isActive) {
allObjectsJob!!.join()
}
// e.g. get object from map
}
}
}
我有以下设置(简化):
- 网络管理员(从后端获取数据)
- 存储库(处理数据并转发到 ui)
我正在寻找一种方法来使用协程执行以下操作:
- 在到达目标屏幕之前,我已经在导航到另一个屏幕时开始预取数据。
- 到达目标屏幕时,我想检查任务是否仍在 运行,如果是,"subscribe" 或等待结果,而不是开始新的冗余网络作业。
有没有办法用协程实现这个?
协程很热门,因此您可以通过在 background 或 UI 上下文中启动任务来推送数据:
job = launch(CommonPool) {
val data = getDataFromBackend().await()
val result = repository.handleData(data).await()
launch(UI) {
// update the UI here based on data or result
}
}
解决方法如下:
当应用程序启动时,它会触发通过存储库预取一些数据。 存储库包含对 运行 协程的作业引用。 当到达目标屏幕时,调用存储库中的另一个方法。在此方法中,应用程序现在只需检查作业是否仍处于活动状态,如果是,它会调用 job.join() 以等待执行完成后再继续。
这是问题的简化。请只关注问题的解决方案: - 启动协程, - 检查协程是否仍然是 运行, - 如果是,在执行其他逻辑之前等待协程完成
在存储库中它看起来如下:
class Repository(private val networkManager: NetworkManager) {
private var allObjectsJob: Job? = null
fun getAllObjects(forceReload: Boolean = false) {
allObjectsJob = launch {
try {
val objects = networkManager.getAllObjects().await().filterNotNull()
// e.g. put all objects in map
} catch (e: HttpException) {
// error handling
}
}
}
fun getObject(id: String) {
launch {
if (allObjectsJob != null && allObjectsJob!!.isActive) {
allObjectsJob!!.join()
}
// e.g. get object from map
}
}
}