В чем разница между launch/join и async/await в Kotlin coroutines



на kotlinx.coroutines библиотека вы можете начать новую сопрограмму, используя либо launchjoin) или asyncawait). В чем разница между ними?

5777   2  

2 ответов:

  • launch используется стреляй и забудь корутин. Это как начать новый поток. Если код внутри launch завершается с исключением, то это рассматривается как непойманные исключение в потоке -- обычно печатается в stderr в приложениях backend JVM и аварийно завершает работу приложений Android. join используется для ожидания завершения запущенной сопрограммы и не распространяет свое исключение. Однако, разбился ребенок coroutine отменяет свой родитель с соответствующим исключением, тоже.

  • async используется запустите сопрограмму, которая вычисляет некоторый результат. Результат представлен экземпляром Deferred и должны использовать await на нем. Неперехваченное исключение внутри async код хранится внутри в результате Deferred и не доставлено в любом другом месте он будет молча отброшен, если не обработан. вы не должны забывать о сопрограмме, которую вы начали с async.

Я нахожу это руководство https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md чтобы быть полезным. Я процитирую основные части

coroutine

по существу, сопрограммы-это легкие нити.

таким образом, вы можете думать о coroutine как о чем-то, что управляет потоком очень эффективным способом.

запуск

fun main(args: Array<String>) {
    launch { // launch new coroutine in background and continue
        delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
        println("World!") // print after delay
    }
    println("Hello,") // main thread continues while coroutine is delayed
    Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
}

так launch запускает фоновый поток, что-то делает и возвращает токен сразу как Job. Вы можете позвонить join на Job блокировать до этого launch поток завершается

fun main(args: Array<String>) = runBlocking<Unit> {
    val job = launch { // launch new coroutine and keep a reference to its Job
        delay(1000L)
        println("World!")
    }
    println("Hello,")
    job.join() // wait until child coroutine completes
}

асинхронные

концептуально асинхронность похожа на запуск. Он запускает отдельную сопрограмму, которая представляет собой легкий поток, который работает одновременно со всеми другими сопрограммами. Разница в том, что запуск возвращает задание и не несет никаких результирующее значение, в то время как async возвращает отложенное-легкое неблокирующее будущее, которое представляет собой обещание предоставить результат позже.

так async запускает фоновый поток, что-то делает и возвращает токен сразу как Deferred.

fun main(args: Array<String>) = runBlocking<Unit> {
    val time = measureTimeMillis {
        val one = async { doSomethingUsefulOne() }
        val two = async { doSomethingUsefulTwo() }
        println("The answer is ${one.await() + two.await()}")
    }
    println("Completed in $time ms")
}

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

так Deferred на самом деле Job. См https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/index.html

interface Deferred<out T> : Job (source)

асинхронный по умолчанию стремится

существует опция laziness для асинхронного использования необязательного параметра start со значением CoroutineStart.ЛЕНИВЫЙ. Он запускает сопрограмму только тогда, когда ее результат необходим некоторым await или если вызывается функция start.

Comments

    Ничего не найдено.