[Android, Kotlin] Coroutine Flow block 내에서 여러 개의 suspend function에 대한 비동기 처리
Android

[Android, Kotlin] Coroutine Flow block 내에서 여러 개의 suspend function에 대한 비동기 처리

조건 : retrofit을 활용한 api 통신을 수행하는 2개의 suspend function을 통해 flow block에서 댓글 목록과 글쓴이의 정보를 가져와 PostInfo 객체로 wrapping 하여 emit해야 함.

 

발생한 문제 : 2개의 suspend function으로 인해 각 suspend function이 끝날 때 까지 해당 flow block이 suspend되므로 연관이 없는 api 통신임에도 불구하고 동기적으로 수행되어 api 통신 속도가 느려짐.

 

기존 코드

 

이로 인해 function 시작부터 comments, user를 emit하는 데까지 걸리는 시간은 평균 1.2 ~ 1.3초가 소요됨.

비동기 처리 전 통신 시간

 

해결 : 처음에는 두 flow를 합치는 zip 연산자를 통해 두 api 연산을 asFlow로 flow로 변환 후 zip 하려 했으나, user api의 경우 collection 형태가 아닌 User 객체 하나만을 받아오므로 flow로의 변환이 불가능했다.

 

이를 위해 flow block 내에서 IO Dispatcher의 context를 사용하는 CoroutineScope를 새로 생성하여 해당 Scope 내에서 async를 통해 api 통신을 비동기적으로 수행하고, await을 통해 두 값이 모두 수신 되었을 때 두 값을 emit 하는 형태로 구현하였다. 

 

개선한 코드

 

function 시작부터 comments, user를 emit하는 데까지 걸리는 시간을 기존 1.2~1.3초에서 async를 통한 두 api 통신의 비동기 처리로 변경하여 0.7~0.8초로 감소시켰다.

비동기 처리 후 통신 시간

 

더 고민할 문제 : 

1. flow block 내에서 새로운 coroutine scope를 생성하지 않고 flow block 내에서 async를 수행할 수 있는 방법이 없는지?

2. collection 형태의 return 값이 아닌 retrofit 통신에 대해서는 flow로의 변환이 절대로 불가능한지?

3. flow의 장점인 다양한 연산자를 활용함으로써 비동기 처리가 가능하지 않을지? (ex. zip, flatMapLatest ...)

 

 

통신 시간이 눈에 띄게 줄어든 것으로 뿌듯하지만, 한편으로는 다른 더 좋은 방법이 있지 않을까 생각해보게 된다.

 

 

 

전체 소스코드 : https://github.com/HunSeongPark/post-sample-hilt-jetpack

 

GitHub - HunSeongPark/post-sample-hilt-jetpack: 기존 post-sample Repository 공부한 기술들로 다시 만들어보기 (MVV

기존 post-sample Repository 공부한 기술들로 다시 만들어보기 (MVVM, Hilt, Coroutine/Flow, DataBinding, Retrofit, Moshi, Jetpack) - GitHub - HunSeongPark/post-sample-hilt-jetpack: 기존 post-sample Repository 공부한 기술들로 ...

github.com