Итак, я переношу пример приложения с RxJava на Kotlin / Anko Corountines, и мне интересно, делаю ли я лучший (первый) подход к нему:
fun getPopulationList() {
val ref = asReference()
async(UI) {
try {
ref().setCurrentState(ViewState.State.LOADING)
val background = bg {
repository.populationResponse().execute().body()
}
ref().let {
it.response = background.await()
it.mvpView?.onGetData(it.response)
it.setCurrentState(ViewState.State.FINISH)
}
} catch (e: Exception) {
e.printStackTrace()
ref().mvpView?.onError(e)
}
}
}
Я использую архитектуру MVP, в которой мой Presenter
базовый класс имеет CompositeSubscription
, а в onDestroy
методе фрагмента или действия просто отписывайтесь и очищайте объект CompositeSubscription
. Но мне интересно, делает ли функция asReference()
из Anko Coroutines то же самое, и нет необходимости сохранять список Deferred<T>
, а затем повторять его и отменять один за другим.
Кстати, если я добавлю Thread.sleep(5000)
для имитации большой транзакции и уничтожения фрагмента, который я вижу в logcat, HTTP-ответ даже после того, как фрагмент не виден / уничтожен, в то время как с RxJava не происходит, поэтому я думаю, что я не использую должным образом.
ОБНОВЛЕНИЕ
fun getPopulationList() {
val ref = asReference()
job = launch(UI) {
try {
ref().setCurrentState(ViewState.LOADING)
val background = bg {
Thread.sleep(5000) //simulate heavy IO
if (isActive) {
repository.populationResponse().execute().body()
} else {
return@bg null
}
}
ref().let {
it.response = background.await()
it.mvpView?.onGetData(it.response)
it.setCurrentState(ViewState.FINISH)
}
} catch (e: Exception) {
RestHttpExceptionHandler().handle(UI, e, ref())
}
}
}
Я могу отменить сопрограмму при вызове метода job.cancel()
в onDestroy()
, но чтобы он заработал, я должен проверить, активно ли задание, и это преобразовать в if / else и данные return or not. Есть ли лучший способ вернуть что-нибудь, когда работа была отменена?