Kotlin - избегайте вложенных обратных вызовов при извлечении нескольких файлов JSON с ION - PullRequest
0 голосов
/ 19 мая 2018

У меня есть некоторый код, который 1] выбирает файл JSON и 2] в зависимости от содержимого этого файла JSON выбирает другой файл JSON.Он использует библиотеку ion .

Код выглядит примерно так (Sidenote - этот код используется в методе onCreate моей деятельности, а e является объектом типа Exception):

Ion.with(applicationContext)
                .load("someURL")
                .asJsonObject()
                .setCallback { e, result->
                    //Do synchronous stuff with the "result" and "e" variables
                    //that determines whether boolean someCondition is true or false 

                    if(somecondition) {
                        Ion.with(applicationContext)
                                .load("https://raw.githubusercontent.com/vedantroy/image-test/master/index.json")
                                .asJsonObject()
                                .setCallback { e, result ->

                                    //Some synchronous code in here

                                }
                    } 

                }

Этот код очень уродливый, и я хотел бы улучшить его, чтобы избавиться от вложенности.Возможно ли это, и если да, то как бы я это сделал?

Я экспериментировал, и, кажется, я могу вызвать метод .then() после setCallback примерно так, где .then() принимает параметр, который является callback объектом:

Ion.with(applicationContext).load("someURL").setCallback { //Lambda Stuff }.then()

так что, возможно, это будет частью решения, но я не уверен.

1 Ответ

0 голосов
/ 20 мая 2018

В проекте Ion есть модуль для сопрограмм Котлина: https://github.com/koush/ion/tree/master/ion-kotlin,, но, похоже, он не находится в рабочем состоянии.К счастью, очень просто добавить свой собственный мост между любым асинхронным API и сопрограммами Kotlin.

Вот пример того, как сделать это для Ion:

private suspend fun fetchIon(url: String): String = suspendCoroutine { cont ->
    Ion.with(this)
            .load(url)
            .asString()
            .setCallback { e, result ->
                if (e != null) {
                    cont.resumeWithException(e)
                } else {
                    cont.resume(result)
                }
            }
}

Теперь вы можете иметь кодкак это:

class MyActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        launch(UI) {
            if (fetchIon("example.org/now") > fetchIon("example.org/deadline") {
                ...
            }
        }
    }

Как видите, вы выполняете асинхронный код ввода-вывода точно так же, как он блокировал.Чтобы обработать ошибки, просто оберните их в try-catch, как и любой «обычный» код.

...