[Kotlin] Flow와 Suspend

이주형·2024년 6월 7일

코틀린에서 Flow와 suspend 함수는 모두 비동기 프로그래밍을 지원하지만, 사용 목적과 방식에 있어서 차이가 있습니다.

📌 Flow

  • Flow는 코틀린의 비동기 스트림을 다루기 위한 API입니다. 여러 값을 시간에 걸쳐 비동기적으로 방출할 수 있습니다.
  • 데이터 스트림을 다루는 경우에 사용됩니다. 예를 들어, 실시간으로 변하는 데이터의 리스트나, 연속적인 이벤트 스트림 등을 처리할 때 유용합니다.
  • Flow는 cold stream이라고도 불리며, collect 함수가 호출되기 전까지는 아무런 작업도 실행하지 않고, collect 함수가 호출되면 그때부터 데이터 스트림을 생성하고 방출하기 시작합니다.
override fun getRooms(): Flow<Resource<List<Room>>> {
        return flow {
            emit(Resource.Loading(true))
            runCatching {
                val querySnapshot = fireStore.collection("rooms").get().await()
                querySnapshot.documents.map { document ->
                    document.toObject(Room::class.java)!!.copy(id = document.id)
                }
            }.onSuccess {
                Log.i("room", "성공")
                emit(Resource.Success(it))
                emit(Resource.Loading(false))
            }.onFailure {
                Log.i("room", "실패 ${it.message}")
                emit(Resource.Error("Error: ${it.message}"))
            }
        }
    }

📌 Suspend 함수

  • suspend 함수는 코루틴 내에서 실행되어야 하는 함수로, 비동기 작업을 동기적인 코드의 형태로 작성할 수 있게 해줍니다.
  • 일반적으로 단일 결과를 반환할 때 사용됩니다. 예를 들어, 네트워크 요청의 결과나, 데이터베이스 쿼리의 결과 등을 가져올 때 사용할 수 있습니다.
  • suspend 함수는 호출한 코루틴을 일시 중단할 수 있으며, 작업이 완료되면 코루틴을 다시 재개합니다.
override suspend fun getRooms(): Resource<List<Room>> {
    return try {
        emit(Resource.Loading(true))
        val querySnapshot = fireStore.collection("rooms").get().await()
        val rooms = querySnapshot.documents.map { document ->
            document.toObject(Room::class.java)!!.copy(id = document.id)
        }
        Log.i("room", "성공")
        Resource.Success(rooms)
    } catch (e: Exception) {
        Log.i("room", "실패 ${e.message}")
        Resource.Error("Error: ${e.message}")
    } finally {
        emit(Resource.Loading(false))
    }
}

📌 배운점

채팅방을 만들 때 suspend를 이용해서 getRooms() 함수를 불러왔더니 채팅방이 만들었을 때 ui에 바로 업데이트가 되지 않는 문제가 생겼다. suspend는 단일 결과값을 불러오기 때문이었다.
suspend를 지우고 Flow로 데이터 스트림을 collectLatest로 관찰하니까 채팅방 생성 즉시 ui가 반영되는 것을 볼 수 있었다.

📌 요약

  • 목적의 차이: suspend 함수는 단일 비동기 작업의 결과를 처리할 때 주로 사용되며, Flow는 여러 값을 시간에 걸쳐 비동기적으로 방출할 때 사용됩니다.
  • 반환 값: suspend 함수는 단일 결과값을 반환하지만, Flow는 여러 값을 방출할 수 있는 스트림을 반환합니다.
  • 사용 케이스: suspend 함수는 주로 데이터를 요청하고 그 결과를 한 번에 처리할 때 사용되고, Flow는 데이터 스트림이나 이벤트 스트림을 지속적으로 관찰하고 반응할 때 사용됩니다.
  • 실행 방식: suspend 함수는 호출 시 즉시 실행되어 결과를 반환하지만, Flow는 collect 메서드를 호출할 때까지 실행되지 않습니다.

0개의 댓글