
Coroutine에서 launch와 async는 모두 새로운 코루틴을 시작하는 데 사용되지만, 반환값을 처리하는 방식이 다릅니다.
이 글에서는 공부한 내용을 정리하며, launch와 async의 차이를 코드 예제와 함께 살펴보겠습니다.
1. launch: 결과를 반환하지 않는 Job
val job = GlobalScope.launch {
delay(1000L)
println("launch 완료!")
}
job.join() // 완료될 때까지 대기
특징
- launch는 Job을 반환합니다.
- Job은 단순히 실행을 시작하고, join()을 호출하기 전까지는 실행 완료 여부를 기다리지 않습니다.
- launch는 비동기적으로 실행되지만, 결과 값을 반환하지 않습니다.
- 즉, 실행은 하지만 결과를 받아서 처리하는 용도가 아닙니다.
2. async: 결과를 반환하는 Deferred
val deferred = GlobalScope.async {
delay(1000L)
"async 완료!"
}
val result = deferred.await() // 결과값을 받을 때까지 대기
println(result)
특징
- async는 Deferred<T> 객체를 반환합니다.
- Deferred<T>는 await()을 호출하면 실행이 완료될 때까지 대기하고 결과 값을 반환합니다.
- 즉, async는 결과 값을 반환받아야 할 때 사용합니다.
3. launch vs async 비교
특징 | launch | async |
반환 값 | 없음 (Job 반환) | 있음 (Deferred<T> 반환) |
실행 방식 | 비동기 실행 후 결과를 기다리지 않음 | await() 호출 시 결과 반환 |
예외 전파 | 즉시 전파됨 | await() 호출 시 전파됨 |
사용 예시 | 단순 실행 | 결과 값을 받아야 할 때 |
4. 언제 사용해야 할까요?
- 단순히 백그라운드에서 실행하고 싶다면 → launch
- 비동기 함수의 결과 값을 받아야 한다면 → async
예제: launch와 async를 함께 사용하기
suspend fun fetchData(): String {
delay(1000L)
return "데이터 로드 완료!"
}
suspend fun main() = coroutineScope {
val job = launch {
println("launch 실행 중...")
delay(500L)
println("launch 완료!")
}
val deferred = async { fetchData() }
job.join() // launch가 끝날 때까지 대기
val result = deferred.await() // async의 결과를 받음
println(result)
}
실행 흐름:
- launch가 실행됨 → 500ms 후 "launch 완료!" 출력
- async 실행 (fetchData() 호출) → 1000ms 후 "데이터 로드 완료!" 출력
- await()을 호출하면 결과 값을 반환받음
5. 추가 설명
1) async는 결과 값을 반환해야 하므로 반드시 await()을 호출해야 합니다.
- Deferred<T>를 반환하므로 await()을 호출해야 최종 결과를 받을 수 있습니다.
- 결과를 기다리기 때문에 자동으로 완료될 때까지 기다리는 효과가 있습니다.
2) launch는 단순 실행용이며, 기본적으로 완료될 때까지 기다릴 필요가 없습니다.
- Job을 반환하지만, join()을 호출하지 않으면 실행이 끝날 때까지 기다리지 않습니다.
- 따라서, 순차 처리가 필요할 때는 join()을 호출해서 실행 완료를 보장해야 합니다.
6. Job과 Deferred의 차이
Job: 코루틴의 실행 상태를 관리하는 객체
- launch는 Job을 반환하지만, 결과 값을 반환하지 않습니다.
- job.join()을 호출하면 코루틴이 끝날 때까지 기다리지만, 결과를 받을 수는 없습니다.
Deferred: 결과 값을 포함하는 비동기 객체
- async는 Deferred<T>를 반환하며, await()을 호출하면 실행 결과를 받을 수 있습니다.
예제:
val job = launch {
delay(1000L)
println("launch 완료!")
}
println(job) // kotlinx.coroutines.JobImpl@xxxx
val deferred = async {
delay(1000L)
"async 완료!"
}
val result = deferred.await()
println(result) // async 완료!
- launch는 실행만 담당하고 결과를 반환하지 않음
- async는 실행 후 await()을 통해 결과를 받을 수 있음
8. 결론
- launch는 실행만 하고 결과를 반환하지 않으며, Job을 반환하여 실행 상태를 관리할 수 있습니다.
- async는 Deferred<T>를 반환하고, await()을 호출해야 실행 결과를 받을 수 있습니다.
- launch는 단순 실행용이며, async는 결과 값이 필요한 경우 사용합니다.
- Job은 실행 상태를 관리하는 객체이며, Deferred<T>는 실행 결과를 포함하는 비동기 객체입니다.
반응형
'Android > Coroutine' 카테고리의 다른 글
[Android/Coroutine] Cold Stream vs Hot Stream 쉽게 이해하기: 언제 어떤 것을 써야 할까? (0) | 2025.03.28 |
---|---|
[Android/Coroutine] SharingStarted.WhileSubscribed(): 효율적인 Flow 공유 전략 (0) | 2025.03.20 |
[Android/Coroutine] 구조화된 동시성이란? (0) | 2025.03.07 |
코루틴과 스레드, 그리고 프로세스: 그 유사성과 차이 (0) | 2025.01.24 |
[Android/Kotlin] 코루틴: Kotlin에서 비동기 프로그래밍을 간소화하는 방법 (1) | 2024.05.29 |