마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

코루틴 async api 2개호출

0 추천
class viewmodel {

  fun test() {
     viewModelScope.launch {

           try {
              val task1 = async { repository.getApi1() }

              val task2 = async { repostiory.getApi2() }

            Log.e("tag", "${task1.await()}")
         } catch(e:Exception) {}
}

이런식으로 되어있는데 아무것도 안나오더라구요 2개를 병렬호출? 하고싶은데 어떻게 하는건가요 ?

https://oozou.com/blog/handle-complex-network-call-on-android-with-kotlin-coroutine-retrofit-2-in-mvvm-9

이거보고 했는데 await다음에 body가 안써집니다

getapi1, api2 메소드는 이런형태입니다

fun getapi1() : Flow<Int> {
 return flow { emit(apiservice.apiCallMehtod()) }
}
수원통학러 (3,570 포인트) 님이 2022년 6월 3일 질문

1개의 답변

0 추천

suspend 함수는 async await가 가능하지만 Flow는 collect를 하셔야 해요. Flow는  cold stream이라고 하는(RxJava와 같다고 보면 됨) 살짝 다른형태의  cocurrency 방법이라고 보시면 됩니다. Flow 를 써야하는 이유가 명확하지 않고 사용시 이점이 있는지 불분명하다면, 그냥  suspend function을 사용하시는게 더 낫다고 봅니다.

그리고 Flow사용시 두개의 Flow를 함께 호출하는 방법은 한가지가 아닙니다. 에를 들면, combine, zip 등이 있구요, 요구사항에 따라 어떤 operator가 적절한지 따져봐야 합니다.

suspend function을 이용해 api 두개를 동시에 호출하는 법.

// 순서 중요. async를 먼저 다 만들고 await를 호출해야 병렬처리가 제대로 됨. 
val apiAsync1 = async { apiservice.apiCallMehtod() }
val apiAsync2 = async { apiservice.apiCallMehtod() }

val result1 = apiAsync1.await()
val result2 = apiAsync2.await()

그리고  launch안에서 중첩으로 couroutine scope 이 있을 때는 SupervisorJob을 사용하지 않으면 제대로 try catch가 동작을 하지 않았던 걸로 기억을 하는데, 제대로 예외 처리가 되는지 확인을 해보세요. 코루틴의 가장 어려운 처리 중의 하나예요.

그리고 try catch를 사용할 때는  아래처럼 CancellationException을 던져서 최상위 코루틴이 처리할 수 있도록 해주어야 합니다.

fun test() {
     viewModelScope.launch {
           try {
              val task1 = async { repository.getApi1() }

              val task2 = async { repostiory.getApi2() }

            Log.e("tag", "${task1.await()}")
         } catch(e: CancellationException) {
               throw e //<----- 추가
         } catch(e:Exception) {
         
         }
    }
}

 

spark (227,830 포인트) 님이 2022년 6월 3일 답변
spark님이 2022년 6월 3일 수정
...