=================
== The Archive ==
=================

[Kotlin Coroutines] 21장. 플로우 만들기

원시값을 가지는 플로우

1
2
3
4
suspend fun main() {
    flowOf(1, 2, 3, 4, 5)
        .collect { print(it) } // 12345
}
1
2
3
4
suspend fun main() {
    emptyFlow<Int>()
        .collect { print(it) } // (nothing)
}

컨버터

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
suspend fun main() {
    listOf(1, 2, 3, 4, 5)
        .asFlow()
        .collect { print(it) } // 12345

    println()

    setOf(1, 2, 3, 4, 5)
        .asFlow()
        .collect { print(it) } // 12345

    println()

    sequenceOf(1, 2, 3, 4, 5)
        .asFlow()
        .collect { print(it) } // 12345
}

함수를 플로우로 바꾸기

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
suspend fun main() {
    val function =
        suspend {
            // this is suspending lambda expression
            delay(1000)
            "UserName"
        }

    function.asFlow()
        .collect { println(it) }
}

// (1 sec)
// UserName
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
private suspend fun getUserName(): String {
    delay(1000)
    return "UserName"
}

suspend fun main() {
    ::getUserName
        .asFlow()
        .collect { println(it) }
}

// (1 sec)
// UserName

플로우와 리액티브 스트림

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
suspend fun main() =
    coroutineScope {
        Flux.range(1, 5).asFlow()
            .collect { print(it) } // 12345

        println()

        Flowable.range(1, 5).asFlow()
            .collect { print(it) } // 12345

        println()

        Observable.range(1, 5).asFlow()
            .collect { print(it) } // 12345
    }
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
suspend fun main(): Unit =
    coroutineScope {
        val flow = flowOf(1, 2, 3, 4, 5)

        flow.asFlux()
            .doOnNext { print(it) } // 12345
            .subscribe()

        println()

        flow.asFlowable()
            .subscribe { print(it) } // 12345

        println()

        flow.asObservable()
            .subscribe { print(it) } // 12345
    }

플로우 빌더

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
private fun makeFlow(): Flow<Int> =
    flow {
        repeat(3) { num ->
            delay(1000)
            emit(num)
        }
    }

suspend fun main() {
    makeFlow()
        .collect { println(it) }
}

// (1 sec)
// 0
// (1 sec)
// 1
// (1 sec)
// 2

플로우 빌더 이해하기

1
2
3
4
5
public fun <T> flowOf(vararg elements: T): Flow<T> = flow {
    for (element in elements) {
        emit(element)
    }
}
1
2
3
4
5
6
7
8
@PublishedApi
internal inline fun <T> unsafeFlow(@BuilderInference crossinline block: suspend FlowCollector<T>.() -> Unit): Flow<T> {
    return object : Flow<T> {
        override suspend fun collect(collector: FlowCollector<T>) {
            collector.block()
        }
    }
}

채널플로우 (channelFlow)

콜백플로우 (callbackFlow)

요약