kotlin сопутствует, почему async {}, возвращенный deferred, возвращает другое значение при вызове await () после добавления оператора Log - PullRequest
0 голосов
/ 17 мая 2019

в котлин сопрограмм образец документа

он имеет образец (немного изменен, чтобы войти в приложение Android для его тестирования)

fun main_test2() = runBlocking<Unit> {
    //sampleStart
    val time = measureTimeMillis {
        println("+++ The answer is ${concurrentSum()}")
    }
    println("+++ Completed in $time ms")
    //sampleEnd
}

suspend fun concurrentSum(): Int = coroutineScope {
    val one = async {
        Log.w("+++", "+++ enter async one{} bf doSomethingUsefulOne()") . //<== cause one.await() returns different value
        doSomethingUsefulOne()
        Log.w("+++", "+++ enter async one{} after doSomethingUsefulOne()")
    }
    val two = async {
        doSomethingUsefulTwo()
    }
    //one.await() + two.await()

    one.await().also {println("+++ one.await(): $it")} + two.await().also {println("+++ two.await(): $it")}
}

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // pretend we are doing something useful here
    return 13
        .also {
            Log.e("+++", "+++ doSomethingUsefulOne() return $it")
        }
}

suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // pretend we are doing something useful here, too
    return 29
        .also {
            Log.e("+++", "+++ doSomethingUsefulTwo() return $it")
        }
}

Я добавил несколько журналов, чтобы показать ход выполнения в suspend fun concurrentSum(),

val one = async {
        Log.w("+++", "+++ enter async one{} bf doSomethingUsefulOne()") . //<=== added log
        doSomethingUsefulOne()
        Log.w("+++", "+++ enter async one{} after doSomethingUsefulOne()") . //<=== added log
    }

но тогда результат становится 85 (потому что one.await () теперь возвращает 56, а не 13) вместо 42,

почему журнал вызывает другой результат?

журнал для без этих двух Log.w () s

com.example.android.kotlincoroutines E/+++: +++ doSomethingUsefulOne() return 13
com.example.android.kotlincoroutines E/+++: +++ doSomethingUsefulTwo() return 29
com.example.android.kotlincoroutines I/System.out: +++ one.await(): 13
com.example.android.kotlincoroutines I/System.out: +++ two.await(): 29
com.example.android.kotlincoroutines I/System.out: +++ The answer is 42
com.example.android.kotlincoroutines I/System.out: +++ Completed in 1009 ms

и журнал с этими двумя Log.w () s:

com.example.android.kotlincoroutines W/+++: +++ enter async one{} bf doSomethingUsefulOne()
com.example.android.kotlincoroutines E/+++: +++ doSomethingUsefulOne() return 13
com.example.android.kotlincoroutines W/+++: +++ enter async one{} after doSomethingUsefulOne()
com.example.android.kotlincoroutines E/+++: +++ doSomethingUsefulTwo() return 29
com.example.android.kotlincoroutines I/System.out: +++ one.await(): 56
com.example.android.kotlincoroutines I/System.out: +++ two.await(): 29
com.example.android.kotlincoroutines I/System.out: +++ The answer is 85
com.example.android.kotlincoroutines I/System.out: +++ Completed in 1006 ms

1 Ответ

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

my bad кодовый блок

val one = async {
        Log.w("+++", "+++ enter async one{} bf doSomethingUsefulOne()")
        doSomethingUsefulOne().also {
            Log.w("+++", "+++ enter async one{} after doSomethingUsefulOne()")
        }
    }

возвращает значение Int из последнего оператора, которым был Log.w (), который возвращает свое собственное int.

должен быть использован.также {} в doSomethingUsefulOne(), чтобы сохранить исходный результат.

не знаю, как закрыть этот вопрос.

...