Как реализовать дополнительный обратный вызов с нуля в Kotlin? - PullRequest
0 голосов
/ 27 мая 2019

У меня есть эта функция, которая прекрасно работает.

inline fun <reified T:Any>String.parse() : T {
    return GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create().fromJson<T>(this, T::class.java)
}

fun request (callback: (MyClass)->Unit) {
    val url = URL("someurl").readText()
    val myObject : MyClass = str.parse()
    callback(myObject)
}

net.request {
    it.myFunction()
    println (it.myString)
}

myObject автоматически заполняется объектом типа MyClass и корректно возвращается к обратному вызову.

Теперь я хочу отловить ошибку, и обратный вызов также может ее вернуть.

fun request (callback: (MyClass?, Exception?)->Unit) {
    try {
        val url = URL("someurl").readText()
        val myObject : MyClass = str.parse()
        callback(myObject, null)
    }
    catch (e: Exception) {
        callback(null, e)
    }
}

net.request { response, error ->
    if (response != null ) { // do something }
    else { // report something }
}

Но это безобразно, потому что, несмотря ни на что, мне придется принудительно вызывать обратный вызов, чтобы всегда иметь два параметра, но одновременно присутствует только один. Поэтому я ищу дополнительные методы обратного вызова. Я хочу иметь возможность вызывать метод следующим образом:

net.request { 
    onSuccess { response -> // do something }
    onError { error -> // report something }
}

Или, возможно:

net.request
    .onSuccess { response -> // do something }
    .onError { error -> // report something }

Если я не хочу обрабатывать ошибку, я просто звоню так:

net.request {
    onSuccess { // do something with 'it' }
}

То, что я могу найти в Интернете, переписывает существующие методы обратного вызова, такие как this . Это не то, что я хочу. Я хочу написать этот обратный вызов с нуля. Просмотр исходного кода иногда тоже не помогает, потому что код написан на Java, а я не понимаю Java. Еще нет.

И я понимаю, что основная библиотека в Kotlin, например, модифицированная или JavaRx, возможно, уже реализует что-то подобное, но я просто хочу знать минимальный необходимый для этого код, поскольку я так учусь. Я просто не могу найти правильный учебник для этого.

1 Ответ

0 голосов
/ 27 мая 2019

Вы можете попробовать эту библиотеку .Это помогает смоделировать успешные / неудачные операции.Ваш обратный вызов может затем принять ваш MyClass объект, завернутый таким образом Result<MyClass, Exception> или просто Result.

Чтобы передать значение вашему обратному вызову, вы затем делаете Callback(Result.of(MyClass)) для успешной операции или Callback(Result.of(Exception())) в случае сбоя.

Затем вы можете использовать обратный вызов, используя любойиз приведенных ниже функций

//if successful
result.success {
}

//if failed
result.failure {
}

//fold is there, if you want to handle both success and failure
result.fold({ value ->
    //do something with value
}, { error ->
    //do something with error
})

Надеюсь, это поможет:)

Редактировать : Как указано @ user2340612, Result был добавлен в stdlib Kotlin.См. здесь для получения более подробной информации

...