Kotlin - coroutine flow

강현성·2021년 8월 7일
1

Kotlin

목록 보기
2/2

📌 Flow

  • 여러개의 값을 순차적으로 보낸다
  • 비동기적인 데이터 스트림
  • flow는 코루틴내에서 실행되어야 한다

💡 Flow create

  • flow builder api를 사용하면 만들 수 있다
class NewsRemoteDataSource(
    private val newsApi: NewsApi,
    private val refreshIntervalMs: Long = 5000
) {
    val latestNews: Flow<List<ArticleHeadline>> = flow {
        while(true) {
            val latestNews = newsApi.fetchLatestNews()
            emit(latestNews) // Emits the result of the request to the flow
            delay(refreshIntervalMs) // Suspends the coroutine for some time
        }
    }
}

// Interface that provides a way to make network requests with suspend functions
interface NewsApi {
    suspend fun fetchLatestNews(): List<ArticleHeadline>
}
  • flow builder는 coroutine block 안에서 실행 되어야하므로 몇 가지 제한 사항이 있다
    -> suspend function이 완료 될 때 까지 중단된다. value emit 해야 되니까
    -> flow builder를 사용하면 다른 coroutine context에서 사용 할 수 없다

💡 Flow collect

  • emit valuse를 collect 연산자로 받아올 수 있다
  • collect는 suspend function이므로 coroutine block 안에서 실행 해야 한다
  • lambda parameter로 값을 받아서 사용 가능
class LatestNewsViewModel(
    private val newsRepository: NewsRepository
) : ViewModel() {

    init {
        viewModelScope.launch {
            // Trigger the flow and consume its elements using collect
            newsRepository.favoriteLatestNews.collect { favoriteNews ->
                // Update View with the latest favorite news
            }
        }
    }
}
  • collect가 중단 되는 경우
    -> collect의 coroutine block이 중단 될 경우
    -> emit value finish

  • flow는 기본적으로 cold and lazy하므로 위에 코드에서 collect가 여러개 있으면 서로 다른 간격으로 여러번 최신 뉴스를 가져온다. 따라서 동시에 가져와서 사용하고 싶으면 shareIn 연산자를 사용하면 된다

💡 Flow catch Exception

  • catch block 을 사용하면 된다
  • catch block에서도 emit이 가능
class NewsRepository(...) {
    val favoriteLatestNews: Flow<List<ArticleHeadline>> =
        newsRemoteDataSource.latestNews
            .map { news -> news.filter { userData.isFavoriteTopic(it) } }
            .onEach { news -> saveInCache(news) }
            // If an error happens, emit the last cached values
            .catch { exception -> emit(lastCachedNews()) }
}

📌 Refercence

profile
안드로이드 주니어 개발자

0개의 댓글