๋ชฉ์ฐจ
์๊ตฌ์ฌํญ ์ ๋ฆฌํ๊ธฐ
๊ตฌํํด์ผํ ์๊ตฌ์ฌํญ์ ์๋์ ๊ฐ๋ค.
๋จผ์ ์ํฉ์ ์ดํดํด๋ณด๋ฉด
๊ธฐ์กด์๋ ํ๋ก์ฐ ์ฌ๋ถ์ ๋ฐ๋ฅธ ์ฒ๋ฆฌ์์ด ํ๋ก์ ๋ฆฌ์คํธ๋ฅผ ๋ฆฌ์ฌ์ดํด๋ฌ๋ทฐ๋ก ๋ณด์ฌ์ฃผ์๋ค.
๋ฐ๋ผ์ Flow<ํ๋ก์ ๋ฆฌ์คํธ>๋ฅผ ๋ฐํํ๋ ์ ์ฆ์ผ์ด์ค๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ํ ์ด๋ฅผ StateFlow ๋ณ์์ ๋ฃ์ด์ฃผ๊ณ UI๋ฅผ ์ ๋ฐ์ดํธํด์ฃผ์๋ค.
์ถ๊ฐ๋ ์ฌํญ์ ๋ด๊ฐ ํด๋น ์ ์ ์ ๋ํ ํ๋ก์ฐ ์ฌ๋ถ์ ๋ฐ๋ผ UI์์์ ๋ณํ๋ฅผ ์ฃผ๋ ๊ฒ์ด์๋ค.
๋ฐ๋ผ์ ํ๋ก์ฐ ๋ฆฌ์คํธ๋ฅผ ๋ฐํํ๋ ์ ์ฆ ์ผ์ด์ค์ ์ ์ ์ ๋ํ ํ๋ก์ฐ ์ฌ๋ถ๋ฅผ ๋ฐํํ๋ ์ ์ฆ ์ผ์ด์ค๋ฅผ ๊ฒฐํฉํ ํ ๊ฒฐํฉํ ๋ฐ์ดํฐ๋ฅผ ๋ฆฌ์ฌ์ดํด๋ฌ๋ทฐ์ ์ ๋ฌํด์ฃผ์ด์ผํ๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ๊ฒฐํฉํ๋ฉด ์ข์๊น?
์ฐพ์๋ณธ ๊ฒฐ๊ณผ combine๊ณผ zip, flatMapLatest์ ๋ํด์ ๋์๋ค.
flow๋ฅผ collectํ๋ ๊ฒ๊ณผ ์ด๋ป๊ฒ ๋ค๋ฅด๊ณ , ๊ฐ ์ฐจ์ด๊ฐ ๋ญ์ง, ๋ด ๊ธฐ๋ฅ ๊ตฌํ์๋ ์ด๋ค ๋ฐฉ์์ด ์ ํฉํ์ง ์์๋ณธ ๊ณผ์ ์ ์ ๋ฆฌํด์ ๊ธฐ๋กํด๋๋ ค๊ณ ํ๋ค.
flow๋ฅผ collect ํ๋ ๊ฒ์ ์๋ฏธ
flow๋ ์ฌ๋ฌ ๊ฐ์ ์์ฐจ์ ์ผ๋ก ๋ด๋ณด๋ผ ์ ์๋ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ด๋ค.
flow๋ฅผ collectํ๊ฒ ๋๋ฉด ๋ฐ์ดํฐ ๋ฐฉ์ถ์ด ์์๋๊ณ , ๋ฐฉ์ถ๋ ์์๋๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
collect ์ฐ์ฐ์๋ ๊ฐ ๊ฐ์ ์์ ํ ๋๊น์ง ์ผ์ ์ค์งํ๊ณ ๊ฐ ๊ฐ์ ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ค.
1๏ธโฃ map ์ฌ์ฉ
Map์ ํตํด ๊ธฐ์กด flow๋ฅผ ๋ณํ์์ผ ๋ด๋ณด๋ผ ์ ์๋ค.
ํ๋ก์ ๋ฆฌ์คํธ๋ฅผ ๊ฐ์ ธ์์ followerUserInfoList.map์ ํตํด ๊ฐ ํ๋ก์ ์ ์ ์ ๋ํด ๋ด๊ฐ ํ๋ก์ ์ค์ธ์ง ์ฌ๋ถ๋ฅผ ํ์ธํ๋ ์ ์ฆ ์ผ์ด์ค ํธ์ถ ํ ๋ฐ์ดํฐ๋ฅผ ๊ฒฐํฉํด์ _mutualFollowerList.value์ ๋ฐ์ํด์ฃผ์๋ค.
fun getFollowerList(userId: String) {
viewModelScope.launch {
getFollowerListUseCase(userId)
.map {
it.followerUserInfoList
.map { userInfo ->
userInfo.userId?.let { it1 ->
val isFollowing = checkIsFollowUseCase(it1).first()?.isFollowing ?: false
MutualFollowUserInfo(
email = userInfo.email,
userId = userInfo.userId,
type = userInfo.type,
nickname = userInfo.nickname,
profileUrl = userInfo.profileUrl,
lastLoginDate = userInfo.lastLoginDate,
introduction = userInfo.introduction,
roles = userInfo.roles,
createDate = userInfo.createDate,
lastModifiedDate = userInfo.lastModifiedDate,
isFollowing = isFollowing,
)
} ?: MutualFollowUserInfo()
}
}.collect {
_mutualFollowerList.value = it
}
}
}
์ด ์ฝ๋๋ก ๊ธฐ๋ฅ์ ์ ์์ ์ผ๋ก ์๋ํ ์ ์์ง๋ง ๋ชจ๋ ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌ๋๋ค๋ ๋จ์ ์ด ์๋ค. ๋ชจ๋ ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌ๋๋ ๊ฒฝ์ฐ ํ๋ก์ ๋ฆฌ์คํธ๊ฐ ๋ง์์ง๋ฉด ๋๋ ค์ง ์ ์๊ฒ ๋ค
๊ฒฐ๊ณผ
ํ์ฌ ๊ตฌํํ ๋ก์ง์ ๊ฒฝ์ฐ ๊ฐ ํ๋ก์์ ๋ํ userId๋ฅผ ์ด์ฉํด์ ๋์ ํด๋น ์ ์ ์ ๋ํ ํ๋ก์ฐ ์ฌ๋ถ๋ฅผ ์ป์ด์ผํ๋ค.
์ฆ ๊ฐ ํ๋ก์์ ๋ํ userId -> ํ๋ก์ฐ ์ฌ๋ถ ๋ผ๋ ์์๊ฐ ์กด์ฌํ๋ค.
๋ฐ๋ผ์ map์ ํตํด ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ ์ ํ๋ค๊ณ ์๊ฐํ๋ค.
๊ทธ๋ฌ๋ ๋ง์ฝ ํ๋ก์ ๋ฆฌ์คํธ๊ฐ ๋์ด๋์ ์์ฐจ์ ์ฒ๋ฆฌ์ ๋๋ฆฐ ์๋๊ฐ ๋๊ปด์ง๋ค๋ฉด ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ก ๊ฐ์ ํด๋ณด๊ธฐ๋ก ํ๋ค.
๋ณ๋ ฌ ์ฒ๋ฆฌ ๋ฐฉ์์ ๋ํด ๊ถ๊ธํด์ ํ ์คํธํด๋ณด์๋ค!
โmap & combine์ ํตํด ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ๊ธฐ
์๊น map์ผ๋ก ์์ฐจ์ฒ๋ฆฌํ์ ๋์ ๋ฌ๋ฆฌ combine์ ํตํด ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํด์ค ๊ฒฝ์ฐ ํ๋ก์์ ๋ํด์ ์ํ ํ์ธ ์์ ~ ์๋ฃ๊ฐ ๋๋ ํ ๋ค์ ํ๋ก์์ ๋ํ ๋ก์ง์ด ์ํ๋๋ ๊ฒ์ด ์๋๋ผ ๊ฐ ํ๋ก์์ ๋ํ ์ํ ํ์ธ ์์ ~ ์๋ฃ๊น์ง๊ฐ ๋ณ๋ ฌ๋ก ์ด๋ฃจ์ด์ง๊ณ ์๋ค.
์ฝ๋๋ฅผ ๋ณด๋ฉด ์๋์ ๊ฐ๋ค!
// 2 . ๋ณ๋ ฌ ์ฒ๋ฆฌ(map & combine ์ฌ์ฉ)
fun getFollowingListParallel(userId: String) {
viewModelScope.launch {
getFollowingListUseCase(userId)
.map { followingResponse ->
println("1. ํ๋ก์ ์๋ต ์ฒ๋ฆฌ ์์")
// null ์ฒดํฌ ํ ๋ฆฌ์คํธ ๊ฐ์ ธ์ค๊ธฐ
val userList = followingResponse?.followingUserInfoList ?: emptyList()
// ๊ฐ ์ฌ์ฉ์๋ณ๋ก Flow ์์ฑ
val followStatusFlows =
userList.map { user ->
println("2. ์ฌ์ฉ์ ${user.userId} ํ๋ก์ฐ ์ํ ํ์ธ ์์")
// ๊ฐ ์ฌ์ฉ์์ ํ๋ก์ฐ ์ํ๋ฅผ ํ์ธํ๋ Flow ์์ฑ
checkIsFollowUseCase(user.userId ?: "").map { followResponse ->
println("3. ์ฌ์ฉ์ ${user.userId} ํ๋ก์ฐ ์ํ ํ์ธ ์๋ฃ")
MutualFollowUserInfo(
email = user.email,
userId = user.userId,
type = user.type,
nickname = user.nickname,
profileUrl = user.profileUrl,
lastLoginDate = user.lastLoginDate,
introduction = user.introduction,
roles = user.roles,
createDate = user.createDate,
lastModifiedDate = user.lastModifiedDate,
isFollowing = followResponse?.isFollowing,
)
}
}
// Flow ๋ฆฌ์คํธ๊ฐ ๋น์ด์๋ ๊ฒฝ์ฐ ์ฒ๋ฆฌ
if (followStatusFlows.isEmpty()) {
flow { emit(emptyList()) }
} else {
// combine์ ์ฌ์ฉํด ๋ชจ๋ Flow๋ฅผ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌ
println("4. ํ๋ก์ ๋ฆฌ์คํธ ๋ณ๋ ฌ ์ฒ๋ฆฌ ์์")
combine(followStatusFlows) { userInfoArray ->
println("5. ํ๋ก์ ๋ฆฌ์คํธ ๋ณ๋ ฌ ์ฒ๋ฆฌ ์๋ฃ")
userInfoArray.toList()
}
}
}.collect {
// ์ฌ๊ธฐ์๋ ๊ฒฐ๊ณผ๊ฐ Flow ํํ๋ก ์์ ์ด๋ป๊ฒ ๋ณํ๋ฅผ ํด์ค ์ง ๋ชจ๋ฅด๊ฒ ์ด์ ์ผ๋จ first()๋ฅผ ์ฌ์ฉํด์ฃผ์๋ค.
_followingList.value = it.first()
}
}
}
map๊ณผ combine์ ๋ํ ์ค๋ช
- map : ์๋์ Flow์์ ๊ฐ ๊ฐ์ ๋ณํ ํจ์๋ฅผ ์ ์ฉํ ๊ฒฐ๊ณผ๋ฅผ ํฌํจํ flow๋ฅผ ๋ฐํํด์ค๋ค.
- combine : ๊ฐ flow์์ ๋ฐฉ์ถ๋ ๊ฐ์ฅ ์ต๊ทผ์ ๊ฐ์ ๊ฒฐํฉํ์ฌ ๋ณํ ํจ์๋ฅผ ์ ์ฉํ์ฌ ์์ฑ๋ ๊ฐ๋ค์ flow๋ฅผ ๋ฐํํ๋ค.
combine์ ํตํด์๋ ๊ฐ Flow๊ฐ ๋์์ ๋ ๋ฆฝ์ ์ผ๋ก ๊ฐ์ ๋ฐฉ์ถํ ์ ์์ด ๋ณ๋ ฌ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค.
๊ณต์ ์์ ๋ ์๋์ ๊ฐ๋ค.
val flow = flowOf(1, 2).onEach { delay(10) }
val flow2 = flowOf("a", "b", "c").onEach { delay(15) }
combine(flow, flow2) { i, s -> i.toString() + s }.collect {
println(it) // Will print "1a 2a 2b 2c"
}
๊ทธ๋ฐ๋ฐ ์ด๋ด ๊ฒฝ์ฐ ๋๋ ํ๋ก์ ๋ฆฌ์คํธ ์ป๊ธฐ -> ๊ฐ ํ๋ก์ ๋ฆฌ์คํธ์ userId ์ป๊ธฐ -> userId๋ก ํ๋ก์ฐ ์ฌ๋ถ ํ์ธํ๊ธฐ
๋ฅผ ์ฒ๋ฆฌํด์ค์ผํ๋ค.
์ด ๋ combine์ผ๋ก ํ ๊ฒฝ์ฐ ํ๋ก์ ์ฌ๋ถ๋ฅผ ์ป๊ธฐ ์ ์ ๊ฐ์ฅ ์ต๊ทผ์ ๊ฐ์ด B ํ๋ก์ ๋ฆฌ์คํธ์ ๊ฐ true์์ ๊ฒฝ์ฐ์ A ํ๋ก์ ๋ฆฌ์คํธ์ B ํ๋ก์ ์ฌ๋ถ๊ฐ ์ ์ฉ๋๋ ๋ฌธ์ ๊ฐ ์๊ธธ ์๋ ์์๊น??
๊ฒฐ๋ก ๋ถํฐ ๋งํ๋ฉด ์๋์๋ค
๋์ ๊ฒฝ์ฐ ๊ฐ ํ๋ก์์ ๋ํ์ฌ userId๋ฅผ ์ด์ฉํด์ ํ๋ก์ฐ ์ฌ๋ถ๋ฅผ ์ป๊ณ ์๋ค. ๊ตฌ์ฒด์ ์ผ๋ก ํ์ด๋ณด๋ฉด
- checkIsFollowUseCase๋ ๊ฐ ํ๋ก์์ userId์ ๋ฐ๋ผ ๊ณ ์ ์ flow๋ก ์๋ํ๊ณ ์๋ค.
- combine์ ๊ฐ flow์์ ๋ฐฉ์ถ๋ ์ต์ ๊ฐ๋ค์ ๋ชจ์ ๋ฐฐ์ด๋ก ์์ฑํ๋ฏ๋ก , ๊ฐ ํ๋ก์์ ๋ํด ์กฐํ๋ ํ๋ก์ ์ํ๊ฐ ๋ค๋ฅธ ํ๋ก์์ ์ ๋ณด์ ์์ด์ง ์๋๋ค.
์ฆ combine์ ํตํด ์ฌ์ฉํ๋ฉด ๊ฐ ํ๋ก์์ ๋ํ ๋์ ํ๋ก์ฐ ์ ๋ณด๋ฅผ ๋งคํํ๊ณ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํด์ค ์ ์๋ค.
'๐ค2024 ์๋๋ก์ด๋ > ๐ฟ ์ํ ํ๋ก์ ํธ ๊ฐ๋ฐ ์ผ์ง' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๋ฒ ํธ์ถ ์ฑ๊ณต ์คํจ ์ฒ๋ฆฌ ] ๋ชจ์กฐ๋ฆฌ ์์ ํ๊ธฐ !!!! (0) | 2024.11.29 |
---|---|
๐ [Android Repository Pattern]์ ์ฌ์ฉํ๋ ์ด์ ์์๋ณด๊ธฐ! (3) | 2024.11.18 |
ํ๋ก์ ํธ์ Jetpack Navigation ์ ์ฉํ๊ธฐ (8) | 2024.10.15 |
๋ฌดํ์คํฌ๋กค์ Paging3 ์ ์ฉํ๊ธฐ (9) | 2024.10.13 |
๐จ๋ฆฌ์ฌ์ดํด๋ฌ๋ทฐ ์คํฌ๋กค ์ ๋ํ๋ ๊ฒฝ๊ณ (3) | 2024.10.13 |