Kotlin - Можно ли вернуть переменную из функции более высокого порядка? - PullRequest
0 голосов
/ 30 января 2020

У меня есть Kotlin функция из отдельной библиотеки, которая принимает функцию в качестве параметра и получает нужную мне переменную из обратного вызова:

object Session {
    fun get(callback: (accessToken: String?) -> Unit): Boolean {
        SomeOtherClass(callback).get()
        return true
     }
}

Затем, чтобы вызвать ее из другого класса, я делаю вызов (в java):

public String getToken() {
     Session.INSTANCE.get((accessToken) -> {
          // I want the method getToken() to be able to 'return accessToken;' 
          // but this call back returns Unit and the get method itself returns Boolean
     });
}

Есть ли способ вернуть переменную accessToken из getToken () напрямую или хотя бы эквивалентное значение? Session.get имеет асин c, поэтому создание «глобальной» переменной возвращает ноль, поскольку значение еще не было назначено. Это одна вещь, которую я попробовал:

public String getToken() {
     String temp;
     Session.INSTANCE.get((accessToken) -> {
          temp = accessToken;
     });
     return temp;
}

Относительно плохо знаком с функциональным программированием, поэтому любая помощь приветствуется!

Ответы [ 2 ]

1 голос
/ 31 января 2020

Вы не можете вернуть возможный результат обратного вызова из метода, который его вызывает, без блокировки потока, который сделал вызов. Причина, по которой существуют обратные вызовы, заключается в том, что вы не будете блокировать поток, который делает вызов. На Android ваше приложение обработает sh сообщением «Приложение не отвечает», если вы заблокируете основной поток на несколько секунд.

Если вы используете Kotlin, вы можете обернуть обратные вызовы библиотеки, используя suspendCancellableCoroutine сделать их совместимыми с сопрограммами. Функции приостановки сопрограмм позволяют возвращать результаты с задержкой.

1 голос
/ 30 января 2020

Если вызов для получения токена доступа - asyn c, вы не можете просто получить его сразу. Это потому, что код внутри вызова get выполняется в другом потоке, в то время как ваш код продолжает работать. Это выглядело бы так:

public String getToken() {
     String temp;                                 // 1. you make a variable
     Session.INSTANCE.get((accessToken) -> {      // 2. get call starts processing
          temp = accessToken;                     
     });
     return temp;                                 // 3. now you return your uninitialized variable
}

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

Лучше всего просто обработать то, что вам нужно в обратном вызове вместо того, чтобы возвращать его в getToken() ...

Не уверен, что вы хотели получить ответ в kotlin или java, но ваш код может выглядеть примерно так в kotlin:

Session.get { token ->
    onToken(token)
}

где onToken обрабатывает любой код, который вам нужен для токена для

fun onToken(token: String) {
    // do whatever code you would've executed after getToken() here
}

Надеюсь, я все объяснил хорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...