본 글은 조세영님의 <코틀린 코루틴의 정석>을 읽고 이를 바탕으로 작성되었습니다.
저번 포스트에서 코루틴 빌더 launch, runBlocking과 그 처리, 취소, 상태에 대해 알아보았다면, 이번 포스트에서는 새로운 코루틴 빌더 async와 그 쓰임에 대해 알아보도록 하자.
먼저 이전 포스트의 launch, runBlocking을 복습하고 async에 대해 알아보자. 코루틴 빌더 함수는 다음과 같다.
코루틴 빌더 함수
- launch: 새로운 코루틴을 시작하고 결과값이 없는 코루틴 객체인 job을 반환한다.
- async: 새로운 코루틴을 시작하고 결과값이 있는 코루틴 객체인 deferred를 반환한다.
- runBlocking: 현재 스레드를 블록하고 코루틴을 시작한다.
위와 같이 launch를 사용하면 새로운 코루틴을 시작할 수 는 있지만 그 결과는 job이어서 받아올 수 없었다. 하지만 async는 deferred를 반환하므로 그 결과를 받아와서 처리할 수 있다는 차이가 있다.
그럼 async는 어떤식으로 사용할까 ?
async를 사용해 Deferred 만들기
public fun <T> CoroutineScope.async(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Deferred<T>
위와 같이 async 또한 context, start, block 의 세가지 인자를 가질 수 있다. 차이는 반환형식이 Deferred 라는 것이다.
그렇다면 Deferred 객체에 대해서 알아보자.
Deferred 객체
- 미래의 어느시점에 결과값이 반환될 수 있음을 표현하는 코루틴 객체 → 결과값을 반환받는 기능이 추가된 job 객체의 특별한 형태이다 (job 인터페이스의 서브타입)
- 코루틴이 실행완료될때 결과값이 반환되므로 언제인지는 정확히 알 수 없고, 수신될때까지 대기해야한다
이처럼 deferred는 결과값 반환 시점을 알 수 없으므로 대기해야하는데, 이때 대기를 위해 사용되는 함수가 await이다.
await
- await 함수는 await의 대상이된 deferred 객체의 실행이 완료될때까지 await가 호출된 코루틴을 일시 중단하고, 완료하면 반환한다
- 요약하면, deferred 객체의 await 함수는 코루틴이 실행 완료될때까지 호출부의 코루틴을 일시 중단한다.
withContext로 async-await 대체하기
fun main() = runBlocking<Unit> {
val result: String = withContext(Dispatchers.IO) {
delay(1000L) // 네트워크 요청
return@withContext "Dummy Response" // 문자열 반환
}
println(result)
}
코루틴 라이브러리에서는 withContext를 제공해 async-await를 대체할 수 있다.
그렇다면 async-await 와 withContext는 어떤 차이를 가질까 ?
async-await VS withContext
async-await
- 새로운 코루틴을 생성해 작업을 처리한다
→ 새로운 코루틴을 만들지먄 await로 순차처리가 가능해 동기적 처리가 가능
withContext
- 실행중이던 코루틴을 유지한채로 코루틴의 실행환경만 바꿔서 작업을 처리
- 즉 코루틴을 만드는 대신 기존의 코루틴에서 CoroutineContext만 바꿔서 처리한다. 위 예제는 IO니까 백그라운드스레드에서 실행
- withContext의 컨텍스트로 변경된다. 즉 Context Switching (문맥교환)이 일어난다.
- 작업 모두 실행하면 이전의 실행환경으로 복귀한다.
→ 코루틴이 유지된 채로 코루틴을 실행하는 실행스레드만 변경되므로 동기적 처리가 가능
'코틀린 > Kotlin Coroutine' 카테고리의 다른 글
[Kotlin][Coroutine] Flow의 이해 (0) | 2024.07.06 |
---|---|
[Kotlin][Coroutine] CoroutineContext (0) | 2024.07.02 |
[Kotlin][Coroutine] CoroutineBuilder와 Job (0) | 2024.06.25 |
[Kotlin][Coroutine] CoroutineDispatcher와 ThreadPool (0) | 2024.05.18 |
[Kotlin][Coroutine] 멀티스레드와 코루틴 (0) | 2024.05.18 |