Android Kotlin协程-如果一段时间后第一个任务没有完成,则启动另一个任务
我使用Kotlin协程从服务器获取数据,我将延迟的数据传递给其他函数。如果服务器在2000毫秒内没有给出答案,我希望从本地数据库中的本地房间数据库中检索对象(如果该对象存在于本地数据库中),但如果我最终从服务器接收到数据,我希望将其保存在本地数据库中以备将来调用。我怎么能做到呢?我曾考虑过使用withTimeout,但在这种情况下,在超时后不需要等待服务器的响应Android Kotlin协程-如果一段时间后第一个任务没有完成,则启动另一个任务,android,database,kotlin,coroutine,kotlin-coroutines,Android,Database,Kotlin,Coroutine,Kotlin Coroutines,我使用Kotlin协程从服务器获取数据,我将延迟的数据传递给其他函数。如果服务器在2000毫秒内没有给出答案,我希望从本地数据库中的本地房间数据库中检索对象(如果该对象存在于本地数据库中),但如果我最终从服务器接收到数据,我希望将其保存在本地数据库中以备将来调用。我怎么能做到呢?我曾考虑过使用withTimeout,但在这种情况下,在超时后不需要等待服务器的响应 override fun getDocument(): Deferred<Document> { return G
override fun getDocument(): Deferred<Document> {
return GlobalScope.async {
withTimeoutOrNull(timeOut) {
serverC.getDocument().await()
} ?: dbC.getDocument().await()
}
}
我想出了一个主意:
fun getDocuments(): Deferred<Array<Document>> {
return GlobalScope.async {
val s = serverC.getDocuments()
delay(2000)
if (!s.isCompleted) {
GlobalScope.launch {
dbC.addDocuments(s.await())
}
val fromDb = dbC.getDocuments().await()
if (fromDb != null) {
fromDb
} else {
s.await()
}
} else {
s.await()
}
}
}
我建议使用kotlinx.coroutines库中的select表达式。
select表达式在网络发出onAwait信号或超时后恢复。在这种情况下,我们返回本地数据
您可能也希望以块的形式加载文档,因为通道也可能有帮助
最后,我们使用kotlinx.coroutines的一个实验性API在示例中,函数onTimeout可能会在库的未来版本中更改谢谢,但在这种情况下,100 ms后,服务器作业被取消。在这种情况下,我希望实现的是返回本地值,但在数据到达时也将来自服务器的数据保存在数据库中。我建议让这两个作业都参与到通道中,以便它将结果立即传递给请求者,否则,如果服务器请求的运行速度低于此速度,则被调用方在2秒后将不会有结果
fun CoroutineScope.getDocumentsRemote(): Deferred<List<Document>>
fun CoroutineScope.getDocumentsLocal(): Deferred<List<Document>>
@UseExperimental(ExperimentalCoroutinesApi::class)
fun CoroutineScope.getDocuments(): Deferred<List<Document>> = async {
supervisorScope {
val documents = getDocumentsRemote()
select<List<Document>> {
onTimeout(100) {
documents.cancel()
getDocumentsLocal().await()
}
documents.onAwait {
it
}
}
}
}