async

코루틴을 만드는 코루틴 빌더 (CoroutineBuilder)

async

async


코루틴을 만드는 코루틴 빌더로 Deferred<T> 객체를 반환하고 비동기 작업 수행에 대한 결과값을 반환하기 때문에 이 결과값을 받아서 다른 작업에 사용할 때 주로 사용한다.

await()

Deferred 객체는 결과값이 있는 비동기 작업을 수행하기 위해 결과값이 없는 Job 을 확장하는 인터페이스로 Job 의 모든 특성을 가지고 있다.

Deferred 에서 결과값을 받기 위해 await() 을 호출하면 실행되고 있는 코루틴은 Deferred 의 결과값을 대기하고 수신되면 반환한다.

import kotlinx.coroutines.*

fun main() = runBlocking {
    println("Start")
    
    println("${deferred1.await()} ${deferred2.await()}")
    // or println("${awaitAll(deferred1, deferred2)}")
    
    println("End")
}

val deferred1: Deferred<String> = GlobalScope.async {
    var i = 0
    while (i < 3) {
        delay(1000)
        i++
    }
    "Result1"
}

val deferred2: Deferred<String> = GlobalScope.async {
    var i = 0
    while (i < 3) {
        delay(1000)
        i++
    }
    "Result2"
}


// Start
// Result1 Result2
// End


start()

코루틴 빌더 asyncstart() 파라미터에 CoroutineStart.Lazy 를 할당하면 해당 코루틴을 호출하는 시점에 실행되도록 할 수 있지만, join() 과 다르게 start() 는 실행만 시키고 종료를 대기하지 않는다. (non-blocking)

import kotlinx.coroutines.*

// deferred.start()
fun main() = runBlocking {
    println("Start")
    deferred.start()
    println("End")
}

val deferred: Deferred<String> = GlobalScope.async(start = CoroutineStart.LAZY) {
    var i = 0
    while (i < 3) {
        delay(1000)
        i++
    }
    "Result"
}


// Start
// End
// Result
import kotlinx.coroutines.*

// deferred.join()
fun main() = runBlocking {
    println("Start")
    deferred.join()
    println("End")
}

val deferred: Deferred<String> = GlobalScope.async(start = CoroutineStart.LAZY) {
    var i = 0
    while (i < 3) {
        delay(1000)
        i++
    }
    "Result"
}


// Start
// Result
// End



Concurrent Using Async (Async 동시 수행)


2개의 함수 실행 시 서로 의존성을 갖지 않는다면 순차 수행보다 동시 수행 시 더 빠른 동작 구현 가능하며 async 사용하여 이를 구현할 수 있다.

import kotlinx.coroutines.*

fun main() = runBlocking { // 순차 수행
    val time = measureTimeMillis {
        val test1 = test1()
        val test2 = test2()
    }
    println("Completed ${time}ms")
}

suspend fun test1(): String {
    delay(1000)
    return "Test1"
}

suspend fun test2(): String {
    delay(2000)
    return "Test2"
}


// Completed 3020ms
import kotlinx.coroutines.*

fun main() = runBlocking { // 동시 수행
    val time = measureTimeMillis {
        val test1 = async { test1() }
        val test2 = async { test2() }
    }
    println("Completed ${time}ms")
}

suspend fun test1(): String {
    delay(1000)
    return "Test1"
}

suspend fun test2(): String {
    delay(2000)
    return "Test2"
}


// Completed 2039ms
essential