이번 글에서는 저번 글에서 빼먹었던 async 코루틴 빌더의 필요성과 어떤 녀석인지 소개해보려고 한다.
async CoroutineBuilder 필요성 이해하기
대체 이 async라는 코루틴 빌더가 존재하는 이유가 뭘까?
이 빌더를 설명하는 글을 보면 대부분 "결과를 반환받는다" 또는 "실행이 완료되기를 기다릴 수 있다"는 멘트가 적혀있다.
나같은 초급 개발자는 "그게 그렇게 다른점인가?"하고 생각할 수 있다.
뭐 결과를 반환받는 것은 다른 점일 수 있지만,
실행이 완료되기를 기다리는 건 launch 코루틴 빌더로도 join() 메소드를 사용하면 가능하기 때문이다.
코드로 launch와 비교해보기
어떤 MutableList 원소를 채워넣는 상황이라고 가정해보자.
그리고 두 코드 블럭을 비교해보자. 과연 어떤 점이 다를까?
fun makeList() {
val someList = mutableListOf<String>()
val job1 = launch {
// ...
someList.add(response1)
}
val job2 = launch {
// ...
someList.add(response2)
}
job1.join()
job2.join()
// someList has 2 elements in this time
}
먼저 launch 코루틴 빌더로 MutableList를 구성하는 코드를 작성해보았다.
fun makeList() {
val deferred1 = async {
// ...
response1
}
val deferred2 = async {
// ...
response2
}
val someList = mutableListOf<String>(deferred1.await(), deferred2.await())
// someList has 2 elements in this time
}
이번에는 async 코루틴 빌더로 MutableList를 구성해봤다.
두 코드 모두 2개의 원소를 가진 리스트를 가지고 있고, 걸리는 시간은 동일하다.
차이점을 발견했을지 모르겠다.
그건 바로, launch를 사용하면 response 값이 외부로 나올 수 없다.
"있는데요?"라고 하려면 코루틴 본문의 값을 외부 변수에 대입해줘야 할 것이다.
그렇다면 async는 어떨까?
async.await()를 사용하면 해당 블럭의 마지막 줄이 리턴 값이 되고 해당 리턴 값이 올 때까지 기다릴 수 있다.
주관적인 느낌으론 async 코루틴 빌더가 하나의 변수처럼 느껴진다.
launch만으로 특정 변수를 제어한다고 하면 어느 스레드 / 코루틴에서 값이 변경되는지 알 수가 없다.
(물론 breakpoint를 하나하나 잡아가면서 보면 할 수는 있겠지만 상상한 해도 끔찍한 디버깅이 될 것이다.)
하지만, async 코루틴 빌더로 지역변수를 만들어 사용한다면 그러한 수고는 덜어낼 수 있을 것이다.
게다가 기본적으로 변수가 여기저기서 값이 변경되는 상황 자체를 피하는 것이 좋다.
'Language > Kotlin' 카테고리의 다른 글
Implement Coroutines Retry (1) | 2024.06.05 |
---|---|
Implement Coroutines Timeout (0) | 2024.05.29 |
Coroutines 기본적인 에러 처리하기(feat. try-catch) (0) | 2024.05.08 |
Coroutines의 Main safety (0) | 2024.05.07 |
Coroutine Builder 이해하기 (0) | 2024.05.02 |