В качестве первого шага вы должны создать suspend fun
s для ваших ApiInterface
и MovieDao
вызовов. Если у них есть некоторый API на основе обратного вызова, вы можете следовать этим официальным инструкциям .
Теперь у вас должно быть
suspend fun ApiInterface.suspendGetMovies(): List<Movie>
и
suspend fun MoviesDao.suspendQueryMovies(): List<Movie>
Теперь вы можете написать этот код:
launch(UI) {
val fromNetwork = async(UI) { apiInterface.suspendGetMovies() }
val fromDb = async(UI) { MoviesDao.suspendQueryMovies() }
select<List<Movie>> {
fromNetwork.onAwait { it }
fromDb.onAwait { it }
}.also { movies ->
// act on the movies
}
}
Основным моментом является select
вызов, который будет одновременно ожидаться в обоих Deferred
с и воздействовать на тот, который завершается первым.
Если вы хотите убедиться, что вы действуете по результатам из сети, вам понадобится еще немного кода, например:
val action = { movies: List<Movie> ->
// act on the returned movie list
}
var gotNetworkResult = false
select<List<Movie>> {
fromNetwork.onAwait { gotNetworkResult = true; it }
fromDb.onAwait { it }
}.also(action)
if (!gotNetworkResult) {
action(fromNetwork.await())
}
Этот код будет действовать на результаты БД, только если они поступят до результатов сети, которые он будет обрабатывать во всех случаях.