Попытка заменить использование обратного вызова на сопрограммы. Имея реализацию, использующую обратный вызов, и не уверена, каков правильный подход, если сопрограммы могут помочь.
Это реализация с обратным вызовом.
Он имеет класс repository
для предоставления данных из локальной базы данных или удаленной сети.
class Repository() {
var callback = //callback is provided by the caller
var isReady = false
var data = null
var firstimeCall = true //only need to get from database at first time call
fun getData(cb: ICallback) {
callback = cb
isReady = false
if (firstimeCall) {
firstimeCall = false
data = doGetDataFromDatabase() //sync call to get data from database
isReady = true
callback.onComplete(this)
}
isReady = false
data = doGetDataFromNetwork() {// async call and lamda as the callback
isReady = true
saveToDatabase(data)
callback.onComplete(this)
}
}
}
repository.getData()
можно вызывать несколько раз, только сначала он сначала вернет данные из базы данных, затем
выход из сети и сохранение, затем вызовите callback.onComplete () для возврата данных.
В любое другое время он будет получать только из сети / сохранять / возвращать данные через обратный вызов.
варианты использования:
- напрямую, используя
Repository
, например
repository.getData() -- 1st time call
repository.getData() -- later call it again
- есть несколько
repositories
, данные из каждого будут объединены в окончательные данные.
для этого случая Aggregator
содержит repositories
и обеспечивает onComplete()
обратный вызов для обработки данных, если все
repositories
готовы.
class Aggregator {
var repos = ArrayList<Repository>()
fun getData() {
for (r in repos) {
Thread {
r.getData(callback)
}.start()
}
}
fun processData(data: ArrayList()) {
......
}
val callback = object ICallback (onComplete{repo->
val hasAllComplete = repos.all {
it.isReady
}
if (hasAllComplete) {
var finalData = ArrayList<Data>()
for (r in repos) {
finalData.add(r.data)
}
processData(finalData)
}
})
}
, поэтому в случае, если у него два Repository
, Aggregator.getData()
будет получать данные из двух репозиториев.
когда один Repository
завершит свой getData()
вызов, он обратится к onComplete () обратного вызова, где
Aggregator
проверит, готовы ли все repositories
к обработке данных.
Тот же поток обратного вызова используется и для сетевого вызова.
Вопрос:
В этом случае, как изменить использование сопрограмм, чтобы только после получения данных из базы данных были завершены оба repositories
,
затем он начнет получать данные из сети, без использования обратных вызовов.