Hanbit the Developer
Kotlin Documentation | Composing suspending functions 본문
Category: Official libraries - Coroutines
문서 링크: https://kotlinlang.org/docs/composing-suspending-functions.html
Sequential by default
fun main() = runBlocking<Unit> {
val time = measureTimeMillis {
val one = doSomethingUsefulOne()
val two = doSomethingUsefulTwo()
println("The answer is ${one + two}")
}
println("Completed in $time ms")
}
suspend fun doSomethingUsefulOne(): Int {
delay(1000L) // pretend we are doing something useful here
return 13
}
suspend fun doSomethingUsefulTwo(): Int {
delay(1000L) // pretend we are doing something useful here, too
return 29
}
The answer is 42
Completed in 2009 ms
Concurrent using async
async()는 launch()처럼 새 코루틴을 시작하는 함수이며, 차이점은 launch는 Job을 반환하고 결과를 반환하지 않는 반면, async는 결과를 나중에 제공할 수 있는 프로미스 객체인 Deferred를 반환한다. 그 결과를 받기 위해서 .await()을 호출할 수 있으며, Deferred는 Job의 일종이기 때문에 코루틴을 취소할 수도 있다.
val time = measureTimeMillis {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")
The answer is 42
Completed in 1016 ms
Lazily started async
async의 start 파라미터로 CoroutineStart.LAZY를 지정하면, 코루틴은 await()을 호출하거나 start()를 호출할 때 시작된다.
val time = measureTimeMillis {
val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
// some computations
one.start() // start the first one
two.start() // start the second one
println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")
*start() 함수를 지우고 실행하면 2초가 걸림에 유의하라.
Async-style functions
// note that we don't have `runBlocking` to the right of `main` in this example
fun main() {
val time = measureTimeMillis {
// we can initiate async actions outside of a coroutine
val one = somethingUsefulOneAsync()
val two = somethingUsefulTwoAsync()
// but waiting for a result must involve either suspending or blocking.
// here we use `runBlocking { ... }` to block the main thread while waiting for the result
runBlocking {
println("The answer is ${one.await() + two.await()}")
}
}
println("Completed in $time ms")
}
// The result type of somethingUsefulOneAsync is Deferred<Int>
@OptIn(DelicateCoroutinesApi::class)
fun somethingUsefulOneAsync() = GlobalScope.async {
doSomethingUsefulOne()
}
// The result type of somethingUsefulTwoAsync is Deferred<Int>
@OptIn(DelicateCoroutinesApi::class)
fun somethingUsefulTwoAsync() = GlobalScope.async {
doSomethingUsefulTwo()
}
다만 이러한 코드 스타일은 다음과 같은 이유로 강력하게 권장되지 않는다: -Async() ~ await() 사이에서 예외가 던져져서 프로그램이 종료되는 경우, ~Async()가 백그라운드에서 계속해서 실행되기 때문에 문제가 발생한다.
Structured concurrency with async
suspend fun concurrentSum(): Int = coroutineScope {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
one.await() + two.await()
}
여기서 문제가 발생하면 coroutineScope의 모든 코루틴이 취소된다.
'Kotlin' 카테고리의 다른 글
Kotlin Documentation | Asynchronous Flow (0) | 2023.05.24 |
---|---|
Kotlin Documentation | Coroutine context and dispatchers (0) | 2023.05.24 |
Kotlin Documentation | Cancellation and timeouts (0) | 2023.05.24 |
Kotlin Documentation | Coroutines and channels - tutorial (0) | 2023.05.24 |
Kotlin Documentation | Coroutines basics (0) | 2023.05.24 |