Zip vs Combine

μ†‘κ·œλΉˆΒ·2023λ…„ 5μ›” 23일
0
post-thumbnail
post-custom-banner

κ°œμš”

μƒν’ˆ 상세 ν™”λ©΄μ—μ„œ μƒν’ˆ 상세 정보(DetailState)와 퀡 λ©”μ‹œμ§€(QuickMessageUiModel) μ •λ³΄μ˜ 결합을 톡해 UI μƒνƒœ 관리λ₯Ό ν•  데이터(QuickMessageViewState)λ₯Ό μƒμ„±ν•΄μ•Όν–ˆλ‹€.

μƒν’ˆ μƒμ„Έμ •λ³΄λŠ” Server APIλ₯Ό 톡해 ν™”λ©΄ μ§„μž… μ‹œ λ¨Όμ € κ°€μ Έμ˜€κ³ , 퀡 λ©”μ‹œμ§€ μ •λ³΄λŠ” Firebase Remote Configλ₯Ό 톡해 κ°€μ Έμ˜¨λ‹€.

이 κ³Όμ •μ—μ„œ λ‹Ήμ—°νžˆ 상황에 μ•Œλ§žμ€ μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•΄μ•Ό ν–ˆμŒμ—λ„ λΆˆκ΅¬ν•˜κ³  κ°€λ³κ²Œ μƒκ°ν•˜κ³  μ§€λ‚˜μ³λ²„λ Έλ‹€.

(Zip을 μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” 상황인데… Combine을..?)
ν•΄λ‹Ή μ‹€μˆ˜λ₯Ό isaac이 μ •ν™•ν•˜κ²Œ μ§šμ–΄ μ£Όμ…¨κ³  μˆ˜μ •ν•œ 과정에 λŒ€ν•œ 글이닀.

Before

	/**
     * μƒν’ˆ 상세 정보와 퀡 λ©”μ‹œμ§€ κ²°ν•©
     */
    fun getCombinedData(): Flow<Pair<DetailState, QuickMessageUiModel>> {
        return combine(_detailState, _quickMessage) { detailState, quickMessage ->
            Pair(detailState, quickMessage)
        }
    }

κ·Έ ν›„μ—λŠ” update λ˜μ–΄μžˆλŠ” μƒν’ˆ 상세 정보(detailState)와 퀡 λ©”μ‹œμ§€ 데이터(quickMessage)λ₯Ό κ²°ν•©ν•˜μ˜€λ‹€.

λ°”λ‘œ 이 λΆ€λΆ„μ—μ„œ λ¬Έμ œκ°€ λ˜μ—ˆλ‹€.
combine의 μš©λ„λ₯Ό 잘 λͺ¨λ₯Έλ‹€λ©΄, 퀡 λ©”μ‹œμ§€μ™€ μƒν’ˆ 상세 μ •λ³΄μ™€μ˜ 연관성을 λͺ¨λ₯Έλ‹€λ©΄ κ·Έλƒ₯ μ§€λ‚˜μΉ  수 μžˆλŠ” μ½”λ“œμ΄λ‹€. (λ‚œ μ•Œμ•˜λŠ”λ° μ™œ,,? πŸ€·β€β™‚οΈ)

이 μ½”λ“œλŠ” λ°˜λ“œμ‹œ Combine보닀 Zip μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 λ§žλ‹€.

Combineκ³Ό Zip에 λŒ€ν•΄ μ„€λͺ…ν•˜κΈ° 전에 상황을 λ¨Όμ € κ°„λž΅ν•˜κ²Œ μ„€λͺ…ν•˜μžλ©΄, 각각의 퀡 λ©”μ‹œμ§€λ₯Ό ν΄λ¦­ν•˜λ©΄ μ–΄λ– ν•œ λ™μž‘μ„ ν•˜κ²Œ λœλ‹€.

이 λ•Œ 퀡 λ©”μ‹œμ§€μ˜ λ‚΄μš©κ³Ό μƒν’ˆ 상세 μ •λ³΄μ—μ„œ λ°›μ•„μ˜¨ itemIdxλ₯Ό ν•¨κ»˜ μ•Œκ³  μžˆμ–΄μ•Όν•œλ‹€.
즉 ν€΅λ©”μ‹œμ§€μ™€ μƒν’ˆ μƒμ„Έμ •λ³΄λŠ” 맀칭이 λ˜μ–΄μ•Ό ν•˜κ³ , 두 κ°œκ°€ 짝을 μ΄λ€˜μ„ λ•Œ 방좜이 λ˜λŠ” 것이 λ§žλ‹€.

zip vs combine

이 λ‘˜μ˜ 곡톡점은 β€˜κ²°ν•©β€™μ„ ν•œλ‹€λŠ” 것이고 μ•„λž˜μ™€ 같은 차이점이 μžˆλ‹€.

zip

  • μ—¬λŸ¬ Flow의 μš”μ†Œλ₯Ό λ™κΈ°ν™”ν•˜κ³  κ²°ν•©ν•΄μ•Ό ν•˜λŠ” κ²½μš°μ— 적합.
  • output FlowλŠ” 두 input Flow λͺ¨λ‘ λ°œν–‰ν•  λ•Œλ§Œ λ°©μΆœν•˜κ³  그렇기에 μˆœμ„œκ°€ μœ μ§€λœλ‹€.
  • 두 input Flow 쀑 ν•˜λ‚˜κ°€ λ‹€λ₯Έ Flow보닀 더 자주 λ°œν–‰ν•˜λŠ” 경우 느린 Flowκ°€ λ”°λΌμž‘μ„ λ•ŒκΉŒμ§€ λŒ€κΈ°ν•œ ν›„ κ²°ν•©λœ μš”μ†Œλ₯Ό λ°œν–‰ν•œλ‹€.

ex) μ‚¬μš©μž ID와 μ‚¬μš©μžμ˜ 이름을 λ§€μΉ­ν•˜μ—¬ λ°©μΆœν•  λ•Œ

private fun main(): Unit = runBlocking {

    println("\nCombine")
    val combine = getIds().combine(getNames()) { id, name ->
        "$id: $name"
    }

    combine.collect {
        log(it)
    }
}

private fun getIds() = flow {
    for (i in 0 until 3) {
        delay(100L)
        emit(ids[i])
    }
}

private fun getNames() = flow {
    for (i in 0 until 3) {
        delay(200L)
        emit(names[i])
    }
}

combine

  • 별닀λ₯Έ 동기화 μš”κ΅¬ 사항 없이 μ—¬λŸ¬ Flow의 μš”μ†Œλ₯Ό κ²°ν•©ν•˜κ³  μž…λ ₯ 흐름이 생성될 λ•Œ λ§ˆλ‹€ μ—…λ°μ΄νŠΈλ₯Ό λ‚΄λ³΄λ‚΄λ €λŠ” κ²½μš°μ— 유용.
  • input Flow 쀑 ν•˜λ‚˜κ°€ λ°œν–‰ν•  λ•Œλ§ˆλ‹€ output이 λ°œν–‰λœλ‹€.
  • 제곡된 transform ν•¨μˆ˜λŠ” 각 Flowμ—μ„œ μ΅œμ‹  μš”μ†Œλ₯Ό κ²°ν•©ν•˜μ—¬ κ²°ν•©λœ μš”μ†Œλ₯Ό μƒμ„±ν•œλ‹€.
  • output FlowλŠ” ν•œ 개의 input Flow보닀 자주 μš”μ†Œλ₯Ό λ°œν–‰ν•  수 있고, input Flowκ°€ λ°œν–‰ν•˜λŠ” 속도에 따라 달라진닀.

ex) μ˜¨λ„μ™€ μŠ΅λ„λ₯Ό ν•¨κ»˜ λ³΄μ—¬μ£ΌλŠ” μ˜¨λ„κ³„μ—μ„œ μ˜¨λ„μ™€ μŠ΅λ„κ°€ 각각 μ—…λ°μ΄νŠΈ 될 λ•Œ λ§ˆλ‹€ λ°©μΆœν•  λ•Œ

private fun main(): Unit = runBlocking {
    val zip = getIds().zip(getNames()) { id, name ->
        "$id: $name"
    }
    println("\nZip")
    zip.collect {
        log(it)
    }

    println("\nCombine")
    val combine = getIds().combine(getNames()) { id, name ->
        "$id: $name"
    }

    combine.collect {
        log(it)
    }
}

private fun getIds() = flow {
    for (i in 0 until 3) {
        delay(100L)
        emit(ids[i])
    }
}

private fun getNames() = flow {
    for (i in 0 until 3) {
        delay(200L)
        emit(names[i])
    }
}

μœ„μ™€ 같은 μ°¨μ΄μ λ“€λ‘œ 인해 λ‘˜μ΄ ν•¨κ»˜ λ°©μΆœλ˜μ–΄μ•Ό ν•˜λŠ” λ‚΄ μƒν™©μ—μ„œλŠ” combine을 μ“°λŠ” 것은 λΉ„νš¨μœ¨μ μ΄λ‹€

After


    /**
     * μƒν’ˆ 상세 정보와 퀡 λ©”μ‹œμ§€ κ²°ν•©
     */
    fun bindGetItemDetailQuickMessage() {
        viewModelScope.launch {
            _detailState.zip(fetchQuickMessage()) { itemDetail, quickMessage ->
                QuickMessageViewState(itemDetail, quickMessage)
            }.collect { result ->
                _quickMessageState.update {
                    it.copy(
                        detail = result.detail,
                        quickMessage = result.quickMessage
                    )
                }
            }
        }
    }
profile
πŸš€ 상상을 μ’‹μ•„ν•˜λŠ” 개발자
post-custom-banner

0개의 λŒ“κΈ€