๋ชฉ์ฐจ
flow๋?
suspend function์ ๋น๋๊ธฐ์ ์ผ๋ก ๋จ์ผ ๊ฐ์ ๋ฆฌํดํ๋ค.
๐ค๊ทธ๋ฐ๋ฐ ๋ง์ฝ ์ฌ๋ฌ ๊ฐ์ ๋ฆฌํดํ๊ณ ์ถ์ผ๋ฉด ์ด๋ป๊ฒ ํ์ง?
์ด ๋ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ด flow์ด๋ค.
flow๋ฅผ ํตํด ๋น๋๊ธฐ์ ์ผ๋ก ๊ณ์ฐ๋ ์ฌ๋ฌ ๊ฐ๋ค์ ๋ฆฌํดํด์ค ์ ์๋ค. ์ฆ flow๋ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ๋ํ๋ธ๋ค.
flow์ emit
emit์ Flow์ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ๋ฐฉ์ถํ๋ ์ญํ ์ ํ๋ค.
flow ์์ฑ์ ๋ด๋ถ์์ emit ํจ์๋ฅผ ํธ์ถํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ฐฉ์ถํ ์ ์๋ค.
flow์ collect
collect์ ์์ emit์ ํตํด flow์์ ๋ฐฉ์ถ๋ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ ์ฒ๋ฆฌํ๋ ์ญํ ์ ํ๋ค.
flow๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋์์ collect ํจ์๋ฅผ ํธ์ถํ์ฌ Flow๋ฅผ ๊ตฌ๋ ํ๊ณ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค.
์ฆ emit์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฐฉ์ถํ๊ณ , collect๋ก ๋ฐ์ดํฐ๋ฅผ ์์งํ๋ ๊ฒ์ด flow์ ๋์ ํ๋ฆ์ด๋ค.
https://kotlinlang.org/docs/flow.html
sequence & suspend function
๋จ์ํ ๋ฆฌ์คํธ ํํ์ List๋ฅผ ์ฌ์ฉํด์ ์ถ๋ ฅํ ์ ์๋ค.
fun simple(): List<Int> = listOf(1, 2, 3)
fun main() {
simple().forEach { value -> println(value) }
}
๋ง์ฝ cpu๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ ์ฐจ๋จ์ฝ๋์ ๊ฒฝ์ฐ์๋ sequence๋ฅผ ํตํด ์ฒ๋ฆฌํด์ค ์ ์๋ค.
์ฌ๊ธฐ์๋ ๊ฐ ์ฐ์ฐ์ 100ms๋งํผ์ ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค.
fun simple(): Sequence<Int> =
sequence { // sequence builder
for (i in 1..3) {
Thread.sleep(100) // pretend we are computing it
yield(i) // yield next value
}
}
simple().forEach { value -> println(value) }
์ด๋ ๊ฒ sequence๋ฅผ ํตํด ์ฒ๋ฆฌํ๋ค๋ฉด ์ด๋ ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ๋ค. ์ฐ๋ฆฌ๋ suspend๋ฅผ ํตํด ๊ฐ ์ฐ์ฐ์์ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ง ์๊ณ ๋ฆฌ์คํธ๋ฅผ ์ถ๋ ฅํด์ค ์ ์๋ค.
suspend fun simple(): List<Int> {
delay(1000) // pretend we are doing something asynchronous here
return listOf(1, 2, 3)
}
fun main() = runBlocking<Unit> {
simple().forEach { value -> println(value) }
}
์ฌ๊ธฐ์ ๋ฐํ๊ฐ์ List<Int>๋ผ๊ณ ์์ฑํ๋ฉด ์ฐ๋ฆฌ๋ ํ๋ฒ์ ๋ชจ๋ ๋ฆฌ์คํธ๋ฅผ ๋ฐํ๋ฐ๋๋ค. ๋น๋๊ธฐ์ ์ผ๋ก ๊ณ์ฐ๋๋ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ๋ํ๋ด๊ธฐ ์ํด์๋ Flow<Int>๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๋๊ธฐ์ ์ธ ๋ฐ์ดํฐ๋ฅผ ํํํ๊ธฐ ์ํด์๋ sequence<Int>๋ฅผ ์ฌ์ฉํ๋ค.
โ๏ธFlow๋ cold์ด๋ค!!!
flow๊ฐ cold๋ผ๋ ๊ฒ ๋ฌด์จ ๋ง์ผ๊น?
flow๋ collect๋๊ธฐ ์ ๊น์ง๋ ์คํ๋์ง ์๋๋ค๋ ์๋ฏธ์ด๋ค.
combine ์ฐ์ฐ์
combine์ ์ฌ๋ฌ ๊ฐ์ flow๋ฅผ ํ๋์ flow๋ก ๊ฒฐํฉํ ๋ ์ฌ์ฉํ ์ ์๋ค. ๊ฒฐ๊ณผ ์๋ก์ด flow๋ฅผ ๋ฐํํ๋ค!
์์์์ ๋ฑ์ฅํ๋ runBlocking์ ์ญํ ์?
์์ ์์ ์์ ๋์จ runblocking์ ์ด๋ค ์ญํ ์ ํด์ค๊น?
์ฝ๋ฃจํด ๊ด๋ จ ์ฝ๋๋ฅผ ์์ฑํ ๋๋ฉด runblocking์ ์์ฃผ ๋ณผ ์ ์์ง๋ง ์ด๋ค ์ํฉ์์ ์ด๋ค ๋ชฉ์ ์ผ๋ก ์ฌ์ฉํ๋์ง ์ ๋๋ก ์ดํดํ์ง ๋ชปํ๋ค.
์ง๊ธ ์ ๋ฆฌํด๋ณด์!! ๐
fun main() = runBlocking {
launch {
delay(1000)
println("Coroutine 1 finished")
}
launch {
delay(2000)
println("Coroutine 2 finished")
}
println("runBlocking finished")
}
๊ณต์๋ฌธ์์ ๋ฐ๋ฅด๋ฉด runblocking์ ์๋ก์ด ์ฝ๋ฃจํด์ ์คํํ๊ณ ํ์ฌ ์ค๋ ๋๋ฅผ ํด๋น ์ฝ๋ฃจํด์ ์๋ฃ๊น์ง ์ฐจ๋จํ๋ ์ญํ ์ ํ๋ค.
runblocking : Runs a new coroutine and blocks the current thread until its completion.
1. runblocing ๋ด๋ถ์์ ์๋ก์ด ์ฝ๋ฃจํด์ ์์ฑํ๋ค.
2. ๊ทธ๋ฆฌ๊ณ ํ์ฌ ์คํ ์ค์ธ ์ค๋ ๋(์ผ๋ฐ์ ์ผ๋ก ๋ฉ์ธ ์ค๋ ๋)๋ฅผ ํด๋น ์ฝ๋ฃจํด์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๊ฒ ํ๋ค.
3. ์ฝ๋ฃจํด์ด ์๋ฃ๋๋ฉด runblocking ํจ์๋ ์ข ๋ฃ๋๋ค.
๋ฉ์ธ ํจ์์์ runblocing์ ์ฌ์ฉํ๋ฉด ๋ฉ์ธ ์ค๋ ๋๊ฐ ์ฝ๋ฃจํด์ด ์๋ฃ๋ ๊นจ์์ง ๊ธฐ๋ค๋ฆฌ๊ฒ ๋๋ค. ๊ทธ๋์ ๋ฉ์ธ ํจ์๊ฐ ์ฝ๋ฃจํด ์คํ์ ๊ธฐ๋ค๋ฆฌ๋ฉด์ ์ข ๋ฃ๋์ง ์๊ณ ์ฝ๋ฃจํด์ ๊ฒฐ๊ณผ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
์ด?! ๊ทผ๋ฐ runcatching์ด๋ผ๋ ๊ฒ๊ณผ๋ ๊ทธ๋ผ ๋ญ๊ฐ ๋ค๋ฅธ๊ฑฐ์ง?
runblocking์ ๋ํด ๋ค์ ์ ๋ฆฌํด๋ณด๋ฉด
- ์๋ก์ด ์ฝ๋ฃจํด์ ์คํํ๊ณ ํด๋น ์ฝ๋ฃจํด์ด ์๋ฃ๋ ๋๊น์ง ํ์ฌ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ๋ค.
- ์ฝ๋ฃจํด ๋ด๋ถ์์ ๋ฐ์ํ ์์ธ๋ฅผ ๊ทธ๋๋ก ์ ํํ๋ค.
- ์ฃผ๋ก ์ด๊ธฐํ ์์ , ํ ์คํธ ์ฝ๋์์ ์ฌ์ฉ๋๋ค.
runcatching
- ๋๋ค ํจ์ ๋ด๋ถ์ ์ฝ๋๋ฅผ ์คํํ๊ณ ์์ธ ๋ฐ์ ์ ์ด๋ฅผ ์ฒ๋ฆฌํ๋ค.
- ์์ธ ๋ฐ์ ์ ๊ฒฐ๊ณผ๋ฅผ Result ๊ฐ์ฒด๋ก ๋ฐํํ๋ค.
- ์์ธ ์ฒ๋ฆฌ๋ฅผ ํตํด ์ฝ๋ฃจํด ์คํ์ ์์ ํ๊ฒ ๊ด๋ฆฌํ ์ ์๋ค.
์ ๋ฆฌํ๋ฉด~~~~
runblocking์ ์ฝ๋ฃจํด์ ๋๊ธฐ์ ์คํ์ ๋ณด์ฅํ๊ณ ๋ฐ๋ผ์ ์ฝ๋ฃจํด์ ์คํ ์์์ ํ์ด๋ฐ์ ์ ์ดํ ๋ ์ฌ์ฉํ๊ณ
runcatching์ ์์ธ ์ฒ๋ฆฌ๋ฅผ ํตํด ์ฝ๋ฃจํด ์คํ์ ์์ ํ๊ฒ ๊ด๋ฆฌํ๋ ์ญํ ์ ํ๋ค!!