@NicolasJafelle Ваш вопрос станет большим и многоплановым. лучше задать новый вопрос.

му я переносю пример приложения из 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 {
                    [email protected] 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 и возвращаемые или нет данные. Есть ли лучший способ вернуть что-то, когда работа была отменена?

Ответы на вопрос(1)

Решение Вопроса

в качестве ссылки() источник это не что иное, как слабая ссылка и метод вызова, чтобы получить ссылку, которая бросаетCancellationException когда объект собран. он не делает ничего, чтобы отменить операцию. просто естьзнать о собранном объекте.

так что вам нужно сохранить ссылку наработа или его подтип для отмены операции.

launch сопрограмма строитель изkotlinx.coroutines возвращает экземпляр задания. вот пример:

private lateinit var job: Job

private fun startCoroutines() {
    val ref = asReference()
    job = launch(UI) {
        try {
            val deferred = async(parent = coroutineContext[Job]) {
                    //do some work
                    result//return
            }

            ref().setData(deferred.await())
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

}


override fun onDestroy() {
    super.onDestroy()
    job.cancel()
}

Примечания:

1- когда тип результата не важенlaunch можно использовать вместоasync.

2- для отмены в дочерних сопрограммах вы должны создать иерархию родительских / дочерних заданий. Я прошел родительский (launch) Job ссылка на детскую сопрограмму (асинхронную) для достижения этой цели.

3- какотмена кооперативная реализация отмены должна быть сделана в асинхронном режиме (см. примерыВот).

3-job.cancel() используется в onDestroy отменяет работу, и это дочерняя асинхронная. это можно сделать в Presenter в шаблоне MVP.

 Nicolas Jafelle29 мар. 2018 г., 19:33
Спасибо! Действительно отличный ответ! Попробую завтра. Не поймал 2 пункта об отмене детских сопрограмм. Во всяком случае, действительно отличный ответ. Если отмена совместная, HTTP-соединение не может быть отменено, верно?
 Nicolas Jafelle03 апр. 2018 г., 22:01
Можете ли вы проверить мой оригинальный пост? обновляется с вашими комментариями.
 David29 мар. 2018 г., 21:34
Благодарю. сопрограммы ничего не знали о значении отмены в вашем случае. Он просто отправит сигнал, и вы получите его с проверкой isActive (см. Примеры отмены в приведенной выше ссылке). Для http Retrofit есть механизм отмены.
 David18 апр. 2018 г., 08:27
@NicolasJafelle Ваш вопрос станет большим и многоплановым. лучше задать новый вопрос.

Ваш ответ на вопрос