#kotlin #asynchronous
#kotlin #асинхронный
Вопрос:
Я создаю следующую переменную:
phoneViewModel = ViewModelProvider(this).get(PhoneViewModel::class.java).also {it.initialRead()}
initialRead() вызывает другую функцию, которая извлекает данные асинхронно. Когда я использую переменную phoneViewModel в своем приложении, приложение завершает работу, поскольку функция initialRead() еще не завершена. Как я могу выполнить другую функцию, например, usePhoneViewModel() после завершения создания «асинхронного» экземпляра?
public fun initialRead(onError: ((errorMessage: String) -> Unit)? = null) {
if (!isDownloadError) {
repository.initialRead(
Action0 { isDownloadError = false},
Action1 { error ->
isDownloadError = true
onError?.let {
val resources = getApplication<Application>().resources
onError.invoke(resources.getString(R.string.read_failed_detail))
}
}
)
}
}
и initialRead в репозитории
fun initialRead(successHandler: Action0?, failureHandler: Action1<RuntimeException>) {
relatedEntities.clear()
if (initialReadDone amp;amp; entities.size > 0) {
observableEntities.setValue(entities)
return
}
var dataQuery = DataQuery().from(entitySet)
if (orderByProperty != null) {
dataQuery = dataQuery.orderBy(orderByProperty, SortOrder.ASCENDING)
}
zGW_EXT_SHIP_APP_SRV_Entities.executeQueryAsync(dataQuery,
Action1 { queryResult ->
val entitiesRead = convert(queryResult.entityList)
entities.clear()
entities.addAll(entitiesRead)
initialReadDone = true
observableEntities.value = entitiesRead
successHandler?.call()
},
failureHandler,
httpHeaders)
}
Комментарии:
1. Пожалуйста, уточните, как именно
initialRead
выполняется асинхронный: возвращает ли он JavaFuture
CompletableFuture
или какой-либо другой подобный тип? Этоsuspend
функция Kotlin? Что-то еще?2. Использовать
LiveData
Ответ №1:
Учитывая эту функцию, я не думаю, что вы сможете. Добавьте onSuccess
аргумент к вашему initialRead
, например:
public fun initialRead(onSuccess: (() -> Unit)? = null, onError: ((errorMessage: String) -> Unit)? = null) {
if (!isDownloadError) {
repository.initialRead(
Action0 {
isDownloadError = false
onSuccess?.invoke()
},
Action1 { error ->
isDownloadError = true
onError?.let {
val resources = getApplication<Application>().resources
onError.invoke(resources.getString(R.string.read_failed_detail))
}
}
)
}
}
а затем передайте то, что вы хотите там сделать:
ViewModelProvider(this).get(PhoneViewModel::class.java).also {
it.initialRead(onSuccess = { usePhoneViewModel() })
}
Комментарии:
1. Спасибо! Но usePhoneViewModel() никогда не вызывается. Есть идеи?
2. Может быть, вы в
if (initialReadDone amp;amp; entities.size > 0)
случае? Но это всего лишь предположение, и я предлагаю попробовать отладить его самостоятельно.3. Только что отлажено, и оно переходит в executeQueryAsync и succesHandler? .вызывается вызов, но моя функция usePhoneViewModel не вызывается, хммм